STOQ API v2 (Beta)
v2.0.0-betaContact: support@stoqapp.com
https://app.stoqapp.com/api/v2/externalProductionSTOQ's action-driven, AI-native external API. Every action is self-describing (description, aliases, notes, JSON request schema) and also reachable via the /help manifest, skill.md, llms.txt, and the MCP server. Public beta — actions and schemas may change before GA. All endpoints require the X-Auth-Token API key.
Authentication
ApiKeyAuthapiKeySend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
API Key: X-Auth-Token in header
Account · Help Docs
Read
Search the STOQ help centre, or read one help article in full. Use for how-to and explanation questions — how a feature works, how to set something up, what a setting means. Search first, then read the article that matches before relaying step-by-step instructions; the snippets are previews, not the whole answer.
Parameters
queryanyqueryurlanyquerylimitanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/help_docs'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/help_docs', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/help_docs')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Integrations
Read
Connection state of Klaviyo, Postscript, Omnisend and Mailchimp, where new signups are synced (Klaviyo, Omnisend, Mailchimp, Shopify customers, with the customer tag), the Mailchimp audience, and the Meta Pixel, Shopify Flow trigger and SplitOrder switches. Returns connected / verified flags only, never keys or tokens.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/integrations'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/integrations', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/integrations')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update the shop's integrations: sync signups to Klaviyo, Omnisend, Mailchimp or Shopify customers (with the customer tag), the Omnisend and Mailchimp API keys and Mailchimp audience, the Meta Pixel, Shopify Flow triggers and the SplitOrder app switch. API keys are write only; reads return connected flags.
Note: Deep partial. omnisend.api_key and mailchimp.api_key are never returned by any read; an empty string removes the saved key. A Mailchimp key is checked by fetching the account's audiences and is not saved when Mailchimp refuses it; mailchimp.list_id must be one of those audiences. Klaviyo connects with OAuth from the Integrations page; this action only turns its sync on or off. flow_triggers.triggers replaces the stored list.
Body
klaviyoanyomnisendanymailchimpanyshopifyanysync_customers_taganymeta_pixelanyflow_triggersanysplit_order_appanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/account/integrations' \
-H 'Content-Type: application/json' \
-d '{
"klaviyo": "string",
"omnisend": "string",
"mailchimp": "string",
"shopify": "string",
"sync_customers_tag": "string",
"meta_pixel": "string",
"flow_triggers": "string",
"split_order_app": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/integrations', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"klaviyo": "string",
"omnisend": "string",
"mailchimp": "string",
"shopify": "string",
"sync_customers_tag": "string",
"meta_pixel": "string",
"flow_triggers": "string",
"split_order_app": "string"
}),
});
const data = await response.json();import requests
payload = {
"klaviyo": "string",
"omnisend": "string",
"mailchimp": "string",
"shopify": "string",
"sync_customers_tag": "string",
"meta_pixel": "string",
"flow_triggers": "string",
"split_order_app": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/account/integrations', json=payload)
data = response.json(){
"klaviyo": "string",
"omnisend": "string",
"mailchimp": "string",
"shopify": "string",
"sync_customers_tag": "string",
"meta_pixel": "string",
"flow_triggers": "string",
"split_order_app": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Languages
Read
The shop's languages: default_locale (the language alerts and the signup widget use), app_locale (the dashboard language), whether multi-language support and translated product titles are on, and, when multi-language is on, the locales published in Shopify.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/languages'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/languages', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/languages')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update the shop's language settings: the dashboard language (app_locale), multi-language alerts and widget, and translated product titles in alerts.
Note: app_locale only changes the merchant dashboard. multi_language_enabled false also turns product_translations_enabled off. product_translations_enabled true needs the read_translations access the Settings page asks for; the call fails until it is granted.
Body
app_localeanymulti_language_enabledanyproduct_translations_enabledanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/account/languages' \
-H 'Content-Type: application/json' \
-d '{
"app_locale": "fr",
"multi_language_enabled": true,
"product_translations_enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/languages', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"app_locale": "fr",
"multi_language_enabled": true,
"product_translations_enabled": true
}),
});
const data = await response.json();import requests
payload = {
"app_locale": "fr",
"multi_language_enabled": True,
"product_translations_enabled": True
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/account/languages', json=payload)
data = response.json(){
"app_locale": "fr",
"multi_language_enabled": true,
"product_translations_enabled": true
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Locations
Read
The store's Shopify locations: id, name, and whether each is active. Use it to name the location ids in back-in-stock delivery settings and in markets.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/locations'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/locations', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/locations')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Markets
Read
The store's Shopify Markets (international selling) configuration: active markets, whether the store sells to multiple markets, each market's countries, and which Shopify locations the merchant has linked to each market (location_ids). Distinct from an offer's market availability or restock-alert locations. Only active markets are returned by default.
Parameters
include_draftsanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/markets'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/markets', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/markets')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Plan Usage
Read
The shop's current STOQ plan and a billing month's usage vs included limits, with the usage-based charges STOQ has metered.
Parameters
periodanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/plan_usage'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/plan_usage', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/plan_usage')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Products
Read
List product variants with their preorder offer link (if any) and back-in-stock waitlist count, sorted by waitlist size (most demand first). search matches product name, variant title, SKU, a storefront/admin product URL, or a numeric/GID product or variant id. With match=product, search returns every variant of each matched product, not only the variants that matched.
Parameters
filteranyallpreorderback_in_stockquerymatchanyvariantproductquerysearchanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/products'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/products', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/products')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Sending
Read
Who sends the shop's customer notifications: the email provider (stoq, klaviyo, flow) and SMS provider, the sender address, sender name and reply-to, the custom sending domain and its DKIM check, whether SMS sending is approved, and whose account sends: email_account and sms_account are "stoq" (STOQ's own email or SMS service, including sms_provider "twilio") or "merchant" (their Klaviyo, Postscript or Shopify Flow with saved credentials); email_sender_domain is "merchant" when mail comes from their verified address.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/sending'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/sending', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/sending')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update who sends the shop's customer notifications: email and SMS provider, sender name, the merchant's own sending address, store domain in SMS links, Klaviyo marketing consent and the Postscript API key (write only). Also the email look every template shares: font, header and description text sizes, and logo size.
Note: Applies to back-in-stock and preorder notifications. use_custom_email_address true needs email_reply_to_address on a domain that is not a free mail provider, and DKIM set up for it before mail goes out from it. postscript_api_key is never returned by any read; it is checked with Postscript and not saved when Postscript refuses it; "" removes it.
Body
email_provideranysms_provideranyemail_from_nameanyuse_custom_email_addressanyemail_reply_to_addressanysms_custom_domain_enabledanyklaviyo_skip_auto_subscribeanypostscript_api_keyanyemail_styleanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/account/sending' \
-H 'Content-Type: application/json' \
-d '{
"email_provider": "string",
"sms_provider": "string",
"email_from_name": "Summer Sneaker Drop",
"use_custom_email_address": "string",
"email_reply_to_address": "string",
"sms_custom_domain_enabled": true,
"klaviyo_skip_auto_subscribe": "string",
"postscript_api_key": "string",
"email_style": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/sending', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email_provider": "string",
"sms_provider": "string",
"email_from_name": "Summer Sneaker Drop",
"use_custom_email_address": "string",
"email_reply_to_address": "string",
"sms_custom_domain_enabled": true,
"klaviyo_skip_auto_subscribe": "string",
"postscript_api_key": "string",
"email_style": "string"
}),
});
const data = await response.json();import requests
payload = {
"email_provider": "string",
"sms_provider": "string",
"email_from_name": "Summer Sneaker Drop",
"use_custom_email_address": "string",
"email_reply_to_address": "string",
"sms_custom_domain_enabled": True,
"klaviyo_skip_auto_subscribe": "string",
"postscript_api_key": "string",
"email_style": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/account/sending', json=payload)
data = response.json(){
"email_provider": "string",
"sms_provider": "string",
"email_from_name": "Summer Sneaker Drop",
"use_custom_email_address": "string",
"email_reply_to_address": "string",
"sms_custom_domain_enabled": true,
"klaviyo_skip_auto_subscribe": "string",
"postscript_api_key": "string",
"email_style": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Settings
Read
One settings section: label, description, settings (the output of the read actions behind it, keyed by block, e.g. settings.widget is GET /back_in_stock/settings/widget), columns (field path => model column) and raw (field path => stored value). Sections: delivery_settings, signup_widget, notification_channels, notification_templates, preorder_notifications, preorder_pages, preorder_storefront_text, integrations, languages.
Parameters
section_idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/settings/{section_id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/settings/{section_id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/settings/{section_id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Setup
Read
The shop's setup state: whether STOQ's app embed is on in the published theme (with the theme editor link that turns it on when it is off), and the getting-started steps for back in stock and preorders: each step's state, how many are done, the next one, and whether setup is complete.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/setup'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/setup', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/setup')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Templates
Translations
Read every translation override on a notification template, plus the full enumeration of translatable field paths, each field's default-locale source text, and every locale the shop has actually published.
Parameters
campaign_typestringrequiredpathpositionanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/templates/{campaign_type}/translations'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/templates/{campaign_type}/translations', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/templates/{campaign_type}/translations')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Account · Translations
Read
Read every translation override on the shop's notify-me button, signup form, and preorder button/modal text, plus the full enumeration of translatable field paths, each field's default-locale source text, and every locale the shop has actually published.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/translations'const response = await fetch('https://app.stoqapp.com/api/v2/external/account/translations', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/account/translations')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Copilot
Settings
Read all back-in-stock settings for a Copilot preview.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Settings
Patch back-in-stock channels, delivery, compliance, tagging, or alerts settings. delivery.batching.mode "multiplier" sends restocked-quantity x multiplier per batch; "fixed" sends batch_size per batch. delivery.stock_threshold must be >= 1. delivery.locations.location_ids and delivery.any_variant.product_ids REPLACE the stored list wholesale; any_variant.all_products true ignores product_ids. Enabling SMS for the first time puts sends on a verification hold until the shop is approved.
Body
channelsanydeliveryanycomplianceanytagginganyalertsanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings' \
-H 'Content-Type: application/json' \
-d '{
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string"
}),
});
const data = await response.json();import requests
payload = {
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings', json=payload)
data = response.json(){
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Signups
Read one back-in-stock signup for a Copilot preview.
Parameters
idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Signups Create
Create one back-in-stock signup for the selected variant. channel must be "email" or "sms"; pass email for the email channel or phone for sms.
Body
channelanyrequiredquantityintegeremailanyphoneanynameanyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/create' \
-H 'Content-Type: application/json' \
-d '{
"channel": "string",
"quantity": 5,
"email": "shopper@example.com",
"phone": "+15551234567",
"name": "Summer Sneaker Drop"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"channel": "string",
"quantity": 5,
"email": "shopper@example.com",
"phone": "+15551234567",
"name": "Summer Sneaker Drop"
}),
});
const data = await response.json();import requests
payload = {
"channel": "string",
"quantity": 5,
"email": "shopper@example.com",
"phone": "+15551234567",
"name": "Summer Sneaker Drop"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/create', json=payload)
data = response.json(){
"channel": "string",
"quantity": 5,
"email": "shopper@example.com",
"phone": "+15551234567",
"name": "Summer Sneaker Drop"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Signups Delete
Delete one pending back-in-stock signup.
Parameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/delete'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/delete', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/delete')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Signups Notify
Queue a notification for one back-in-stock signup.
Body
allow_resendanyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/notify' \
-H 'Content-Type: application/json' \
-d '{
"allow_resend": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"allow_resend": true
}),
});
const data = await response.json();import requests
payload = {
"allow_resend": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/notify', json=payload)
data = response.json(){
"allow_resend": true
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Signups Transfer
Transfer one pending back-in-stock signup to another variant. to_shopify_variant_id is the target Shopify variant ID (obtainable from get_offer_variants).
Body
to_shopify_variant_idanyrequiredto_shopify_product_idanyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/transfer' \
-H 'Content-Type: application/json' \
-d '{
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001"
}),
});
const data = await response.json();import requests
payload = {
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/transfer', json=payload)
data = response.json(){
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Notifications
List
List back-in-stock notifications (the send log) in this shop, paginated.
Note: status=blocked surfaces sends that did not go out, with blocked_reason (the stored text), blocked_reason_code and blocked_reason_label. Every response has a summary (total, sent, blocked, blocked_by_reason) that counts every row matching the filters, not only this page. group_by=product returns counts per product (sent, blocked, and blocked by reason code) instead of rows, paginated by product. A bare from/to date is that whole day in the shop's time zone.
Parameters
channelanyemailsmspushquerystatusanysentblockedquerygroup_byanyproductqueryvariant_idanyqueryproduct_idanyqueryfromanyquerytoanyquerypageanyqueryper_pageanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/notifications'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/notifications', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/notifications')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Read
Read one back-in-stock notification (a single send-log entry).
Parameters
idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/notifications/{id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/notifications/{id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/notifications/{id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Orders
List
List orders placed after a back-in-stock alert, paginated. search matches order number/name, customer name, email, a Shopify order id (10+ digits), an order gid (gid://shopify/Order/), or a Shopify admin order URL.
Parameters
pageanyqueryper_pageanyquerysearchanyquerycustomer_idanyqueryfromanyquerytoanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/orders'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/orders', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/orders')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Products
Read
Read per-product back-in-stock configuration: notify-me button visibility (always_show / when_out_of_stock / never_show), restock message and assigned template for each variant, plus whether the shop-level per-product customization toggle is on. Each row also has the variant's pending and total signups and its lifetime back-in-stock units sold and revenue. Filter with shopify_product_id, shopify_variant_id, overrides_only=true or has_waitlist=true. Rows are sorted by pending signups, most first.
Parameters
shopify_product_idanyqueryshopify_variant_idanyqueryoverrides_onlyanyqueryhas_waitlistanyquerylimitanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/products'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/products', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/products')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update per-product back-in-stock configuration for one or more products or variants (the "Back in stock alerts -> Products" tab). targets is a list; a target with shopify_variant_id changes just that VARIANT, a target with only shopify_product_id changes EVERY variant of that product. The same field values are applied to every target, so send one call per distinct set of values. button_visibility is one of "always_show" (notify-me button shown even while the item is IN stock -- WARNING: this also DISABLES automatic back-in-stock alerts for that variant, so the merchant has to notify signups manually), "when_out_of_stock" (the default: button appears only when out of stock and alerts send automatically) or "never_show" (button hidden on the storefront). restock_message is the free-text note shown under the button (e.g. "Back in stock March 15"); send an empty string to clear it. template is a back-in-stock template name or id, or "default" to fall back to the global widget design. automatic_alerts_enabled (true/false) directly sets whether this variant receives an automatic back-in-stock alert on restock -- the same control as the variant's own "Enable/Disable alerts" button, independent of button_visibility. Use this to fix a variant showing "Disabled" for automatic alerts in get_bis_products (get_bis_products.automatic_alerts_enabled), not button_visibility. If both button_visibility: "always_show" and automatic_alerts_enabled are sent in the same call, automatic_alerts_enabled wins. Per-product visibility/message/template values only take effect while the shop-level toggle configure_notify_me_enabled is on; when it is off this action refuses rather than store values that would not apply, unless enable_customization: true is passed, which turns the toggle on as part of this change (a no-op when already on). automatic_alerts_enabled is NOT gated by configure_notify_me_enabled -- it applies regardless. per_product_customization_enabled (true/false), sent on its own with no targets, turns that shop-level toggle on or off (off = the tab's "Disable per-product overrides").
Note: Bulk-safe: a single call may address up to 100 targets and writes them in one transaction with the Shopify metafield syncs fired once for the whole batch. A target STOQ has no product_variants row for is looked up in the shop's Shopify catalog; when it is there, its rows are created (one per variant for a product target) and the change is applied to them. Ids in neither are reported in unmatched. Deleting a back-in-stock template clears it from every product/variant it was assigned to (they fall back to the global design); template CRUD lives on the templates capability.
Body
targetsanybutton_visibilityanyrestock_messageanytemplateanyenable_customizationanyautomatic_alerts_enabledanyper_product_customization_enabledanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/products' \
-H 'Content-Type: application/json' \
-d '{
"targets": "string",
"button_visibility": "string",
"restock_message": "string",
"template": "string",
"enable_customization": "string",
"automatic_alerts_enabled": true,
"per_product_customization_enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/products', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"targets": "string",
"button_visibility": "string",
"restock_message": "string",
"template": "string",
"enable_customization": "string",
"automatic_alerts_enabled": true,
"per_product_customization_enabled": true
}),
});
const data = await response.json();import requests
payload = {
"targets": "string",
"button_visibility": "string",
"restock_message": "string",
"template": "string",
"enable_customization": "string",
"automatic_alerts_enabled": True,
"per_product_customization_enabled": True
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/products', json=payload)
data = response.json(){
"targets": "string",
"button_visibility": "string",
"restock_message": "string",
"template": "string",
"enable_customization": "string",
"automatic_alerts_enabled": true,
"per_product_customization_enabled": true
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Notification Status
Notification/waitlist status for one product variant: pending signups, total alerts sent, the 5 most recent send batches (each with what triggered it), and the shop's delivery settings -- the usual reason a restock produced no send yet.
Parameters
variant_idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/products/{variant_id}/notification_status'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/products/{variant_id}/notification_status', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/products/{variant_id}/notification_status')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Reports
List
List every available back-in-stock report (name, description, aliases, url).
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Conversions
Time-series of orders attributed to back-in-stock alerts, the revenue recovered, and the distinct customers who placed them.
Note: Unscoped requests read the daily rollups plus today, as the Overview chart does; there unique_customers is summed per day, so a customer who bought on two days counts twice. range=all_time starts at the install date.
Parameters
fromanyquerytoanyqueryrangeanyqueryvariant_idanyqueryproduct_idanyquerychannelanyquerymarket_idanyquerygranularityanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Conversions Export
Async CSV export of the back-in-stock conversions time series.
Body
fromanytoanyvariant_idanyproduct_idanychannelanygranularityanysort_byanydirectionanypageanyper_pageanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Engagement
Back-in-stock "Notify me" button engagement/funnel analytics: impressions, clicks, click rate, signups, and signup rate — the same numbers on the merchant's back-in-stock Engagement dashboard. Rates use unique shoppers. This is button engagement, not conversion — for orders placed by notified customers use /back_in_stock/reports/summary.
Parameters
fromanyquerytoanyquerymarket_idanyqueryvariant_idsanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/engagement'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/engagement', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/engagement')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Exports
Check the status of an async report export and get the download URL when ready.
Parameters
job_idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/exports/{job_id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/exports/{job_id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/exports/{job_id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Notifications
Time-series of back-in-stock notifications sent, split by channel (email/sms/push), with blocked sends and the emails and delivered SMS messages behind them.
Note: sent counts notifications by when they were sent; blocked by when they were attempted. emails_sent and sms_delivered count the messages behind them; unscoped requests read those two from the daily rollups, as the Overview chart does. range=all_time starts at the install date.
Parameters
fromanyquerytoanyqueryrangeanyqueryvariant_idanyqueryproduct_idanyquerychannelanyquerymarket_idanyquerygranularityanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Notifications Export
Async CSV export of the back-in-stock notifications time series.
Body
fromanytoanyvariant_idanyproduct_idanychannelanygranularityanysort_byanydirectionanypageanyper_pageanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Products In Demand
Ranked variants (or products) by back-in-stock demand: signups waiting now, signups created in the window, last requested.
Note: pending counts the waitlist now and ignores the window; total counts signups created in the window. group_by=product ranks products instead of variants.
Parameters
group_byanyvariantproductqueryfromanyquerytoanyqueryrangeanyqueryvariant_idanyqueryproduct_idanyquerychannelanyquerymarket_idanyquerysort_byanyquerydirectionanyquerypageanyqueryper_pageanyqueryResponse
Success — example response shown.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand')
data = response.json(){
"window": {
"from": "2026-05-26T00:00:00Z",
"to": "2026-06-25T23:59:59Z"
},
"sort_by": "pending",
"direction": "desc",
"rows": [
{
"shopify_variant_id": 47284734423096,
"shopify_product_id": 8784906035384,
"variant_title": "Blue / Medium",
"product_title": "Classic Sneaker",
"pending": 47,
"total": 89,
"last_requested_at": "2026-06-25T11:30:00Z"
},
{
"shopify_variant_id": 47284734455864,
"shopify_product_id": 8784906035384,
"variant_title": "Red / Large",
"product_title": "Classic Sneaker",
"pending": 23,
"total": 56,
"last_requested_at": "2026-06-25T09:15:00Z"
}
],
"meta": {
"total_count": 287,
"page": 1,
"per_page": 50,
"total_pages": 6
}
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Products In Demand Export
Async CSV export of the back-in-stock products-in-demand report.
Body
fromanytoanyvariant_idanyproduct_idanychannelanygranularityanysort_byanydirectionanypageanyper_pageanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Signups
Time-series of back-in-stock signups created (day/week/month), with how many of them are still waiting and how many signups were notified in each bucket.
Note: signups counts signups created in the bucket; pending is how many of those are waiting now; notified counts signups notified in the bucket. Unscoped requests read signups from the daily rollups, as the Overview chart does. range=all_time starts at the shop's install date.
Parameters
fromanyquerytoanyqueryrangeanyqueryvariant_idanyqueryproduct_idanyquerychannelanyquerymarket_idanyquerygranularityanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Signups Export
Async CSV export of the back-in-stock signups time series.
Body
fromanytoanyvariant_idanyproduct_idanychannelanygranularityanysort_byanydirectionanypageanyper_pageanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Summary
Back-in-stock totals over a window: signups created, signups waiting now, signups and distinct customers notified in the window, attributed orders, conversion rate and recovered revenue. range=all_time covers the shop's whole history.
Note: Unscoped requests match the Back in Stock Overview: all-time signups, orders and revenue come from the shop's lifetime counters, a window's from the daily rollups plus today (source says which). pending and pending_by_channel are the waitlist now and ignore the window. last_notified_at is the latest send for the scope, whatever the window.
Parameters
fromanyquerytoanyqueryrangeanyqueryvariant_idanyqueryproduct_idanyquerychannelanyquerymarket_idanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Summary Export
Async CSV export of the back-in-stock summary report.
Body
fromanytoanyvariant_idanyproduct_idanychannelanygranularityanysort_byanydirectionanypageanyper_pageanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"variant_id": "45000000001",
"product_id": "78000000001",
"channel": "string",
"granularity": "string",
"sort_by": "string",
"direction": "string",
"page": "string",
"per_page": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Wait Duration
How long back-in-stock shoppers have been waiting: median wait days, the longest wait, and a binned wait-time histogram (paid plans only). Also returns total_waiting, the current pending/opted-in signup count.
Parameters
variant_idanyqueryproduct_idanyquerymarket_idanyqueryfromanyquerytoanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/wait_duration'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/wait_duration', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/wait_duration')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Settings
Read
Read all back-in-stock settings for the shop.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update back-in-stock settings for the shop.
Note: Accepts any combination of capability blobs: channels, delivery, compliance, tagging, alerts, widget — deep partial, delegated to the capability PATCHes, errors accumulated. Boolean toggles are set via this PATCH (or the capability PATCH): channels.email.enabled, channels.sms.enabled, channels.push.enabled, delivery.batching.enabled, delivery.locations.filter_enabled, delivery.any_variant.enabled, compliance.optin_required, tagging.order_tags.enabled, alerts.signups_threshold.notify, alerts.scheduled_reports.daily, alerts.scheduled_reports.weekly, alerts.scheduled_reports.monthly, widget.placement.enabled — e.g. { channels: { sms: { enabled: true } } }.
Body
channelsanydeliveryanycomplianceanytagginganyalertsanywidgetanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings' \
-H 'Content-Type: application/json' \
-d '{
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string",
"widget": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string",
"widget": "string"
}),
});
const data = await response.json();import requests
payload = {
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string",
"widget": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings', json=payload)
data = response.json(){
"channels": "string",
"delivery": "string",
"compliance": "string",
"tagging": "string",
"alerts": "string",
"widget": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Alerts
Read back-in-stock merchant alert and scheduled report settings.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Alerts
Update back-in-stock merchant alert and scheduled report settings.
Note: Toggles set via this PATCH: signups_threshold.notify, signup_alerts.enabled, scheduled_reports.daily, scheduled_reports.weekly, scheduled_reports.monthly, notify_on_alert_sent — e.g. { scheduled_reports: { weekly: true } }. signups_threshold.count is the per-variant signup count that triggers the high-demand merchant alert email. signup_alerts.enabled turns on an immediate email to the merchant for every individual signup, sent to signup_alerts.email. scheduled_reports.email is the address that receives the daily/weekly/monthly summary reports. notify_on_alert_sent emails the merchant whenever back-in-stock alerts are sent to customers. merchant_emails.product_updates and merchant_emails.theme_published turn STOQ's own emails to the merchant on or off.
Body
signups_thresholdanysignup_alertsanyscheduled_reportsanynotify_on_alert_sentanymerchant_emailsanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts' \
-H 'Content-Type: application/json' \
-d '{
"signups_threshold": "string",
"signup_alerts": "string",
"scheduled_reports": "string",
"notify_on_alert_sent": "string",
"merchant_emails": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"signups_threshold": "string",
"signup_alerts": "string",
"scheduled_reports": "string",
"notify_on_alert_sent": "string",
"merchant_emails": "string"
}),
});
const data = await response.json();import requests
payload = {
"signups_threshold": "string",
"signup_alerts": "string",
"scheduled_reports": "string",
"notify_on_alert_sent": "string",
"merchant_emails": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts', json=payload)
data = response.json(){
"signups_threshold": "string",
"signup_alerts": "string",
"scheduled_reports": "string",
"notify_on_alert_sent": "string",
"merchant_emails": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Channels
Read back-in-stock notification channel settings.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Channels
Update back-in-stock notification channel toggles, and the master switch for automatic back-in-stock alerts.
Note: Channel toggles are set via this PATCH: email.enabled, sms.enabled, push.enabled — e.g. { sms: { enabled: true } }. alerts_enabled false stops automatic back-in-stock alerts on every channel, whatever the channel switches say. Enabling SMS for the first time triggers a restricted-content verification check; sends may be held until the shop is verified.
Body
alerts_enabledanyemailanysmsanypushanyResponse
Success — example response shown.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels' \
-H 'Content-Type: application/json' \
-d '{
"channels": {
"email": {
"enabled": true
},
"sms": {
"enabled": true
},
"push": {
"enabled": false
}
}
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"channels": {
"email": {
"enabled": true
},
"sms": {
"enabled": true
},
"push": {
"enabled": false
}
}
}),
});
const data = await response.json();import requests
payload = {
"channels": {
"email": {
"enabled": True
},
"sms": {
"enabled": True
},
"push": {
"enabled": False
}
}
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels', json=payload)
data = response.json(){
"channels": {
"email": {
"enabled": true
},
"sms": {
"enabled": true
},
"push": {
"enabled": false
}
}
}{
"channels": {
"email": {
"enabled": true
},
"sms": {
"enabled": true
},
"push": {
"enabled": false
}
},
"delivery": {
"batching": {
"enabled": false
},
"stock_threshold": 1,
"locations": {
"filter_enabled": false,
"location_ids": []
}
},
"compliance": {
"optin_required": false,
"optin_method": "single"
},
"tagging": {
"order_tags": {
"enabled": false,
"tags": []
}
},
"alerts": {
"scheduled_reports": {
"weekly": true,
"email": "merchant@example.com"
}
}
}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Compliance
Read back-in-stock compliance settings (double opt-in).
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/compliance'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/compliance', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/compliance')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Compliance
Update back-in-stock compliance settings (double opt-in).
Note: The double-opt-in toggle is set via this PATCH: optin_required — e.g. { optin_required: true }. When enabled, signups must confirm via email before they are eligible for notifications (GDPR double opt-in).
Body
optin_requiredanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/compliance' \
-H 'Content-Type: application/json' \
-d '{
"optin_required": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/compliance', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"optin_required": "string"
}),
});
const data = await response.json();import requests
payload = {
"optin_required": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/compliance', json=payload)
data = response.json(){
"optin_required": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Delivery
Read back-in-stock delivery settings (batching, stock threshold, locations, any-variant).
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Delivery
Update back-in-stock delivery settings (batching, stock threshold, locations, any-variant, password-protected sending, market setup, market-based alerts, alerts on publish).
Note: Deep partial. Toggles set via this PATCH: batching.enabled, locations.filter_enabled, any_variant.enabled — e.g. { batching: { enabled: true } }. batching.mode is an enum: 'multiplier' (batch size = restocked quantity x batching.multiplier) or 'fixed' (batch size = batching.batch_size); batching.wait_hours is the wait between batches. stock_threshold is the minimum restocked quantity before notifications send (>= 1). any_variant.all_products is a boolean: when true, any-variant alerts apply to every product and any_variant.product_ids is ignored; when false, only the listed products qualify. locations.location_ids and any_variant.product_ids are arrays of Shopify numeric ids and are replaced wholesale when present. send_while_password_protected is a boolean: false (default) holds back-in-stock alerts while the storefront password is on (signups stay pending for the next restock); true sends anyway. market_setup is "single_market" or "multiple_markets"; market_locations_enabled turns on market-based alerts; alert_on_publish also alerts when a product is published.
Body
batchinganystock_thresholdanylocationsanyany_variantanysend_while_password_protectedanymarket_setupanymarket_locations_enabledanyalert_on_publishanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery' \
-H 'Content-Type: application/json' \
-d '{
"batching": "string",
"stock_threshold": "string",
"locations": "string",
"any_variant": "string",
"send_while_password_protected": "string",
"market_setup": "gid://shopify/Market/12345",
"market_locations_enabled": "gid://shopify/Market/12345",
"alert_on_publish": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"batching": "string",
"stock_threshold": "string",
"locations": "string",
"any_variant": "string",
"send_while_password_protected": "string",
"market_setup": "gid://shopify/Market/12345",
"market_locations_enabled": "gid://shopify/Market/12345",
"alert_on_publish": "string"
}),
});
const data = await response.json();import requests
payload = {
"batching": "string",
"stock_threshold": "string",
"locations": "string",
"any_variant": "string",
"send_while_password_protected": "string",
"market_setup": "gid://shopify/Market/12345",
"market_locations_enabled": "gid://shopify/Market/12345",
"alert_on_publish": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery', json=payload)
data = response.json(){
"batching": "string",
"stock_threshold": "string",
"locations": "string",
"any_variant": "string",
"send_while_password_protected": "string",
"market_setup": "gid://shopify/Market/12345",
"market_locations_enabled": "gid://shopify/Market/12345",
"alert_on_publish": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Tagging
Read back-in-stock order tagging settings.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/tagging'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/tagging', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/tagging')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Tagging
Update back-in-stock order tagging settings.
Note: The toggle is set via this PATCH: order_tags.enabled — e.g. { order_tags: { enabled: true } }. order_tags.tag is the single tag applied to Shopify orders attributed to a back-in-stock notification (default 'STOQ-back-in-stock').
Body
order_tagsanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/tagging' \
-H 'Content-Type: application/json' \
-d '{
"order_tags": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/tagging', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"order_tags": "string"
}),
});
const data = await response.json();import requests
payload = {
"order_tags": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/tagging', json=payload)
data = response.json(){
"order_tags": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Widget
Read the storefront back-in-stock signup widget configuration: the notify-me button, where it appears, and the signup form's copy, styling and inputs.
Parameters
localeanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Widget
Update the storefront back-in-stock signup widget: the notify-me button (text, colors, corner radius, font, position), where the button appears (product, collection, home, search, preorder pages, and whether the whole widget is enabled), and the signup form's copy, success/error messages, colors, which inputs are collected and the double opt-in email text. button.position is "auto" (in-flow, directly below the sold-out add-to-cart button), "float-right" or "float-left" (a floating tab pinned to that edge of the page) or "specific" (after the element placement.selectors.product finds). placement.selectors holds the CSS selectors that place the button on product, collection, home and search pages; placement.hide_by_tag limits the widget by product tag; form.inline shows the form on the page instead of a popup; custom.css and custom.javascript run on every storefront page. form.fields.sms_first is a boolean: true shows the SMS field before email. form.fields.sms_default_country is a lowercase ISO 3166-1 alpha-2 code (e.g. "us", "gb", "ca", "au"). form.fields.sms_allowed_countries takes { add: [...], remove: [...] } of those same codes and edits the stored list in place — it never replaces it, so one country can be added or dropped without resending the rest; an empty allowed list means every country is allowed. Colors must be hex (#RRGGBB); radii are integers in pixels. Pass an optional top-level locale (e.g. "fr") to write the text fields for that language only.
Note: Deep partial. Groups: button, placement (with selectors and hide_by_tag), form.copy, form.messages, form.style, form.fields, form.inline, optin, branding, custom. Selectors, the on-page form, custom CSS/JavaScript and the app proxy path change what every shopper sees; a wrong value can hide the widget. Channel enables (email/sms/push), optin_required and the merchant signup alert live on the other settings capabilities.
Body
localeanybuttonanyplacementanyformanyoptinanybrandinganycustomanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget' \
-H 'Content-Type: application/json' \
-d '{
"locale": "fr",
"button": "string",
"placement": "string",
"form": "string",
"optin": "string",
"branding": "string",
"custom": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"locale": "fr",
"button": "string",
"placement": "string",
"form": "string",
"optin": "string",
"branding": "string",
"custom": "string"
}),
});
const data = await response.json();import requests
payload = {
"locale": "fr",
"button": "string",
"placement": "string",
"form": "string",
"optin": "string",
"branding": "string",
"custom": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget', json=payload)
data = response.json(){
"locale": "fr",
"button": "string",
"placement": "string",
"form": "string",
"optin": "string",
"branding": "string",
"custom": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Signups
List
List back-in-stock signups (the waitlist) in this shop, paginated.
Note: status compiles notified_at / unsubscribed_at / blocked_at into one lifecycle value; email and phone filters match partial values on the signup or its customer; query matches the customer's name, email or phone with one term (use email/phone instead to match only one). summary counts every signup matching the filters by status (total, pending, notified, blocked, unsubscribed), not only this page. A bare from/to date is that whole day in the shop's time zone.
Parameters
channelanyemailsmspushquerystatusanypendingnotifiedblockedunsubscribedqueryvariant_idanyqueryproduct_idanyqueryqueryanyqueryemailanyqueryphoneanyqueryfromanyquerytoanyquerypageanyqueryper_pageanyqueryResponse
Success — example response shown.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/signups')
data = response.json(){
"signups": [
{
"id": 5847392,
"status": "pending",
"channel": "email",
"contact": "john@example.com",
"quantity": 2,
"variant": {
"shopify_variant_id": 47284734423096,
"shopify_product_id": 8784906035384,
"title": "Blue / Medium"
},
"customer": {
"id": 9284756,
"email": "john@example.com",
"name": "John Doe"
},
"notifications_sent": 0,
"last_notified_at": null,
"created_at": "2026-06-25T13:45:30Z"
},
{
"id": 5847393,
"status": "notified",
"channel": "sms",
"contact": "+14155552671",
"quantity": 1,
"variant": {
"shopify_variant_id": 47284734455864,
"shopify_product_id": 8784906035384,
"title": "Red / Large"
},
"customer": {
"id": 9284757,
"email": "jane@example.com",
"name": "Jane Smith"
},
"notifications_sent": 1,
"last_notified_at": "2026-06-24T10:30:00Z",
"created_at": "2026-06-20T15:20:15Z"
}
],
"meta": {
"total_count": 147,
"page": 1,
"per_page": 50,
"total_pages": 3
}
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Create
Create a back-in-stock signup (add a customer to the waitlist for a variant).
Note: email is required for the email channel, phone for sms. shopify_product_id is resolved from the variant when omitted. Returns 409 when a pending signup already exists for the same contact + variant + channel.
Body
channelanyemailsmsrequiredshopify_variant_idanyrequiredquantityintegershopify_product_idanyemailanyphoneanynameanyResponse
Success — example response shown.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups' \
-H 'Content-Type: application/json' \
-d '{
"channel": "email",
"shopify_variant_id": 47284734423096,
"shopify_product_id": 8784906035384,
"email": "john@example.com",
"quantity": 2,
"name": "John Doe"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"channel": "email",
"shopify_variant_id": 47284734423096,
"shopify_product_id": 8784906035384,
"email": "john@example.com",
"quantity": 2,
"name": "John Doe"
}),
});
const data = await response.json();import requests
payload = {
"channel": "email",
"shopify_variant_id": 47284734423096,
"shopify_product_id": 8784906035384,
"email": "john@example.com",
"quantity": 2,
"name": "John Doe"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/signups', json=payload)
data = response.json(){
"channel": "email",
"shopify_variant_id": 47284734423096,
"shopify_product_id": 8784906035384,
"email": "john@example.com",
"quantity": 2,
"name": "John Doe"
}{
"id": 5847392,
"status": "pending",
"channel": "email",
"contact": "john@example.com",
"quantity": 2,
"variant": {
"shopify_variant_id": 47284734423096,
"shopify_product_id": 8784906035384,
"title": "Blue / Medium"
},
"customer": {
"id": 9284756,
"email": "john@example.com",
"name": "John Doe"
},
"optin": {
"required": false,
"confirmed": null
},
"notifications_sent": 0,
"last_notified_at": null,
"created_at": "2026-06-25T13:45:30Z"
}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Read
Read one back-in-stock signup's full representation.
Parameters
idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Delete
Delete a pending back-in-stock signup (remove the customer from the waitlist).
Note: Pending signups only; deleting an already-notified signup returns 409.
Parameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X DELETE 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}', {
method: 'DELETE',
});
const data = await response.json();import requests
response = requests.delete('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Notify
Send the back-in-stock notification for one signup now, regardless of stock state.
Note: 409 when the signup was already notified and allow_resend is not set.
Body
allow_resendanyParameters
idstringrequiredpathResponse
Success — example response shown.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}/notify' \
-H 'Content-Type: application/json' \
-d '{
"allow_resend": false
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}/notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"allow_resend": false
}),
});
const data = await response.json();import requests
payload = {
"allow_resend": False
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}/notify', json=payload)
data = response.json(){
"allow_resend": false
}{
"signup_id": 5847392,
"queued": true
}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Bulk Delete
Delete up to 1000 pending back-in-stock signups in one request.
Note: Pending-only: 422 listing the offending ids when any signup was already notified.
Body
signup_idsArray<string>requiredResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups/bulk_delete' \
-H 'Content-Type: application/json' \
-d '{
"signup_ids": [
"sgn_a1b2c3"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/bulk_delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"signup_ids": [
"sgn_a1b2c3"
]
}),
});
const data = await response.json();import requests
payload = {
"signup_ids": [
"sgn_a1b2c3"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/bulk_delete', json=payload)
data = response.json(){
"signup_ids": [
"sgn_a1b2c3"
]
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Bulk Notify
Send back-in-stock notifications for up to 1000 signups in one request.
Note: Responds 200 when all succeed, 207 with { success, failed } on partial failure. Already-notified signups fail unless allow_resend is set.
Body
signup_idsArray<string>requiredallow_resendanyResponse
Success — example response shown.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups/bulk_notify' \
-H 'Content-Type: application/json' \
-d '{
"signup_ids": [
"5847392",
"5847393",
"5847394"
],
"allow_resend": false
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/bulk_notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"signup_ids": [
"5847392",
"5847393",
"5847394"
],
"allow_resend": false
}),
});
const data = await response.json();import requests
payload = {
"signup_ids": [
"5847392",
"5847393",
"5847394"
],
"allow_resend": False
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/bulk_notify', json=payload)
data = response.json(){
"signup_ids": [
"5847392",
"5847393",
"5847394"
],
"allow_resend": false
}{
"success": [
5847392,
5847393
],
"failed": [
{
"signup_id": "5847394",
"error": "Already notified — pass allow_resend to send again"
}
]
}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Transfer
Move back-in-stock signups from one variant to another (variant merges or replacements).
Note: scope picks which signups move: pending (default), notified, or all. Signups that would duplicate a pending signup on the target variant are dropped. from_shopify_product_id is resolved from the source variant when omitted.
Body
from_shopify_variant_idanyrequiredto_shopify_variant_idanyrequiredto_shopify_product_idanyrequiredscopeanypendingnotifiedallfrom_shopify_product_idanyResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/signups/transfer' \
-H 'Content-Type: application/json' \
-d '{
"from_shopify_variant_id": "45000000001",
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001",
"scope": "pending",
"from_shopify_product_id": "78000000001"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from_shopify_variant_id": "45000000001",
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001",
"scope": "pending",
"from_shopify_product_id": "78000000001"
}),
});
const data = await response.json();import requests
payload = {
"from_shopify_variant_id": "45000000001",
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001",
"scope": "pending",
"from_shopify_product_id": "78000000001"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/signups/transfer', json=payload)
data = response.json(){
"from_shopify_variant_id": "45000000001",
"to_shopify_variant_id": "45000000001",
"to_shopify_product_id": "78000000001",
"scope": "pending",
"from_shopify_product_id": "78000000001"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Back In Stock · Templates
Read
Read a localized back-in-stock notification template. stage is "initial" (the back-in-stock alert), "reminder" (the follow-up reminder) or "signup_thank_you" (the email/SMS sent right after a customer signs up). The numbers 0 and 1 are accepted as aliases for initial and reminder. Includes enabled, the stage's on/off switch.
Parameters
stagestringrequiredpathlocalestringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update a localized back-in-stock notification template. stage is "initial" (the back-in-stock alert), "reminder" (the follow-up reminder) or "signup_thank_you" (the email/SMS sent right after a customer signs up); 0 and 1 are aliases for initial and reminder. enabled (true/false) turns the reminder or the signup thank-you on or off; the initial alert cannot be disabled here. email_button_destination and sms_link_destination each accept only "checkout" or "product". Social links (email_facebook_link, email_instagram_link, email_pinterest_link, email_twitter_link, email_tiktok_link, email_whatsapp_link, email_youtube_link) take the profile URL without https:// and show as icons in the email; they are the ONLY place for social links — never put links in the footer. Colours (email_background_color, email_text_color, email_button_background_color, email_button_text_color) are flat hex fields — there is no nested style object. email_template_enabled (true/false) is the "Use HTML template" switch: false goes back to the standard STOQ email, true uses the custom HTML email template (email_template). Colours, corner radii and the Judge.me reviews block are shared by every stage of the alert; social links, the social icon colour and email_unsubscribe_text by every template of the shop.
Note: Deep partial over the template fields plus the stage's enabled switch. Rejects HTML except in email_template and email_css_config, and runs Template validations and callbacks. email_button_destination and sms_link_destination each accept only "checkout" or "product" (product page).
Body
enabledbooleanemail_template_enabledbooleanemail_reviews_enabledbooleanemail_button_textstringemail_button_destinationstringemail_descriptionstringemail_footerstringemail_preheaderstringemail_headerstringemail_subjectstringpush_bodystringpush_button_textstringpush_titlestringsms_bodystringsms_link_destinationstringklaviyo_flow_namestringklaviyo_sms_flow_namestringemail_background_colorstringemail_text_colorstringemail_button_background_colorstringemail_button_text_colorstringemail_facebook_linkstringemail_instagram_linkstringemail_pinterest_linkstringemail_twitter_linkstringemail_tiktok_linkstringemail_whatsapp_linkstringemail_youtube_linkstringemail_social_icon_colorstringemail_section_colorstringemail_border_radiusanyemail_button_border_radiusanyemail_unsubscribe_textstringemail_reviews_titlestringemail_reviews_countanyemail_reviews_min_ratinganyemail_css_configstringemail_templatestringParameters
stagestringrequiredpathlocalestringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"email_template_enabled": true,
"email_reviews_enabled": true,
"email_button_text": "Preorder now",
"email_button_destination": "string",
"email_description": "string",
"email_footer": "string",
"email_preheader": "string",
"email_header": "string",
"email_subject": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"push_title": "string",
"sms_body": "string",
"sms_link_destination": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_facebook_link": "string",
"email_instagram_link": "string",
"email_pinterest_link": "string",
"email_twitter_link": "string",
"email_tiktok_link": "string",
"email_whatsapp_link": "string",
"email_youtube_link": "string",
"email_social_icon_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_border_radius": "string",
"email_unsubscribe_text": "Preorder now",
"email_reviews_title": "string",
"email_reviews_count": 5,
"email_reviews_min_rating": "string",
"email_css_config": "string",
"email_template": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"email_template_enabled": true,
"email_reviews_enabled": true,
"email_button_text": "Preorder now",
"email_button_destination": "string",
"email_description": "string",
"email_footer": "string",
"email_preheader": "string",
"email_header": "string",
"email_subject": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"push_title": "string",
"sms_body": "string",
"sms_link_destination": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_facebook_link": "string",
"email_instagram_link": "string",
"email_pinterest_link": "string",
"email_twitter_link": "string",
"email_tiktok_link": "string",
"email_whatsapp_link": "string",
"email_youtube_link": "string",
"email_social_icon_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_border_radius": "string",
"email_unsubscribe_text": "Preorder now",
"email_reviews_title": "string",
"email_reviews_count": 5,
"email_reviews_min_rating": "string",
"email_css_config": "string",
"email_template": "string"
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"email_template_enabled": True,
"email_reviews_enabled": True,
"email_button_text": "Preorder now",
"email_button_destination": "string",
"email_description": "string",
"email_footer": "string",
"email_preheader": "string",
"email_header": "string",
"email_subject": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"push_title": "string",
"sms_body": "string",
"sms_link_destination": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_facebook_link": "string",
"email_instagram_link": "string",
"email_pinterest_link": "string",
"email_twitter_link": "string",
"email_tiktok_link": "string",
"email_whatsapp_link": "string",
"email_youtube_link": "string",
"email_social_icon_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_border_radius": "string",
"email_unsubscribe_text": "Preorder now",
"email_reviews_title": "string",
"email_reviews_count": 5,
"email_reviews_min_rating": "string",
"email_css_config": "string",
"email_template": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}', json=payload)
data = response.json(){
"enabled": true,
"email_template_enabled": true,
"email_reviews_enabled": true,
"email_button_text": "Preorder now",
"email_button_destination": "string",
"email_description": "string",
"email_footer": "string",
"email_preheader": "string",
"email_header": "string",
"email_subject": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"push_title": "string",
"sms_body": "string",
"sms_link_destination": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_facebook_link": "string",
"email_instagram_link": "string",
"email_pinterest_link": "string",
"email_twitter_link": "string",
"email_tiktok_link": "string",
"email_whatsapp_link": "string",
"email_youtube_link": "string",
"email_social_icon_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_border_radius": "string",
"email_unsubscribe_text": "Preorder now",
"email_reviews_title": "string",
"email_reviews_count": 5,
"email_reviews_min_rating": "string",
"email_css_config": "string",
"email_template": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Preorders · Developer Settings
Read
The preorder Developer settings: whether dev mode is on, and the custom CSS selectors that place the Preorder button and each preorder element on product pages. Shop-wide, not per offer. The selectors are used only while dev_mode_enabled is true.
Response
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/developer_settings'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/developer_settings', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/developer_settings')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Preorders · Notifications
Read
Read shop-level preorder notification settings for a locale. email_account and sms_account say whose account sends: "stoq" or "merchant" (see GET /account/sending).
Parameters
localestringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update shop-level preorder notification settings for a locale. This edits shop-level toggles, provider (email_provider/sms_provider), sender name, and shipping-update / payment-collection copy — NOT the confirmation email body (use update_preorder_template for that). email_provider and sms_provider accept only the shop's enabled provider keys.
Note: Deep partial. Validates booleans, provider enums, locale, length, and plain-text content; then runs Setting validations and provider/SMS verification callbacks.
Body
preorder_email_enabledbooleanpreorder_sms_enabledbooleanpreorder_cancellation_enabledbooleannotify_payment_collection_enabledbooleanemail_provideranystoqklaviyoflowsms_provideranytwiliotelnyxinfobipklaviyopostscriptemail_from_namestringshipping_update_subjectstringshipping_update_headerstringshipping_update_descriptionstringpayment_collection_email_subjectstringpayment_collection_email_headerstringpayment_collection_email_descriptionstringpayment_collection_email_button_textstringklaviyo_shipping_update_flow_namestringklaviyo_payment_failed_flow_namestringParameters
localestringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}' \
-H 'Content-Type: application/json' \
-d '{
"preorder_email_enabled": true,
"preorder_sms_enabled": true,
"preorder_cancellation_enabled": true,
"notify_payment_collection_enabled": true,
"email_provider": "stoq",
"sms_provider": "twilio",
"email_from_name": "Summer Sneaker Drop",
"shipping_update_subject": "2026-07-01T00:00:00Z",
"shipping_update_header": "2026-07-01T00:00:00Z",
"shipping_update_description": "2026-07-01T00:00:00Z",
"payment_collection_email_subject": "string",
"payment_collection_email_header": "string",
"payment_collection_email_description": "string",
"payment_collection_email_button_text": "Preorder now",
"klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
"klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"preorder_email_enabled": true,
"preorder_sms_enabled": true,
"preorder_cancellation_enabled": true,
"notify_payment_collection_enabled": true,
"email_provider": "stoq",
"sms_provider": "twilio",
"email_from_name": "Summer Sneaker Drop",
"shipping_update_subject": "2026-07-01T00:00:00Z",
"shipping_update_header": "2026-07-01T00:00:00Z",
"shipping_update_description": "2026-07-01T00:00:00Z",
"payment_collection_email_subject": "string",
"payment_collection_email_header": "string",
"payment_collection_email_description": "string",
"payment_collection_email_button_text": "Preorder now",
"klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
"klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
}),
});
const data = await response.json();import requests
payload = {
"preorder_email_enabled": True,
"preorder_sms_enabled": True,
"preorder_cancellation_enabled": True,
"notify_payment_collection_enabled": True,
"email_provider": "stoq",
"sms_provider": "twilio",
"email_from_name": "Summer Sneaker Drop",
"shipping_update_subject": "2026-07-01T00:00:00Z",
"shipping_update_header": "2026-07-01T00:00:00Z",
"shipping_update_description": "2026-07-01T00:00:00Z",
"payment_collection_email_subject": "string",
"payment_collection_email_header": "string",
"payment_collection_email_description": "string",
"payment_collection_email_button_text": "Preorder now",
"klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
"klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}', json=payload)
data = response.json(){
"preorder_email_enabled": true,
"preorder_sms_enabled": true,
"preorder_cancellation_enabled": true,
"notify_payment_collection_enabled": true,
"email_provider": "stoq",
"sms_provider": "twilio",
"email_from_name": "Summer Sneaker Drop",
"shipping_update_subject": "2026-07-01T00:00:00Z",
"shipping_update_header": "2026-07-01T00:00:00Z",
"shipping_update_description": "2026-07-01T00:00:00Z",
"payment_collection_email_subject": "string",
"payment_collection_email_header": "string",
"payment_collection_email_description": "string",
"payment_collection_email_button_text": "Preorder now",
"klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
"klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Preorders · Offer Lookup
Find
Resolve one preorder offer from an exact id or a fuzzy name match. Returns the full offer (same shape as GET /preorders/offers/:id) on a unique match. If name matches more than one offer, returns {ambiguous: true, candidates: [...]} instead of guessing -- re-call with the chosen id. Omit both id and name for the most recently created offer.
Parameters
idanyquerynameanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/offer_lookup'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offer_lookup', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offer_lookup')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Preorders · Offers
List
List preorder offers in this shop, paginated. search matches offer name, internal name, or an attached product's title. status filters by enabled/disabled/scheduled. market_ids narrows to offers restricted to those Shopify markets. sort orders by created date, name, or revenue.
Note: expand adds capability blocks to each row, in the same shape as their own reads: inventory, shipping, payments, markets, products (comma-separated or an array). summary counts every offer matching the filters by state (total, active, scheduled, paused, ended), not only this page.
Parameters
statusanyallenableddisabledscheduledquerysortanycreated_at desccreated_at ascinternal_name ascinternal_name descpreorder_revenue descpreorder_revenue ascquerypageanyqueryper_pageanyquerysearchanyquerymarket_idsanyqueryexpandanyqueryResponse
Success — example response shown.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/offers'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers')
data = response.json(){
"offers": [
{
"id": "gid://shopify/SellingPlan/1",
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026",
"status": "draft",
"created_at": "2026-06-25T10:30:45Z",
"updated_at": "2026-06-25T10:30:45Z"
},
{
"id": "gid://shopify/SellingPlan/2",
"name": "Winter Collection",
"internal_name": "winter-2026",
"status": "active",
"created_at": "2026-06-20T14:15:30Z",
"updated_at": "2026-06-22T09:45:12Z"
}
],
"meta": {
"total_count": 2,
"page": 1,
"per_page": 50,
"total_pages": 1
}
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Create
Create a new preorder offer.
Body
nameanyinternal_nameanyResponse
Success — example response shown.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers' \
-H 'Content-Type: application/json' \
-d '{
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}),
});
const data = await response.json();import requests
payload = {
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers', json=payload)
data = response.json(){
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}{
"id": "gid://shopify/SellingPlan/1",
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026",
"status": "draft",
"created_at": "2026-06-25T10:30:45Z",
"updated_at": "2026-06-25T10:30:45Z",
"variants": {
"count": 0,
"url": "/api/v2/external/preorders/offers/1/products/variants"
}
}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Read
Read a preorder offer's full representation.
Parameters
idstringrequiredpathResponse
Success — example response shown.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}')
data = response.json(){
"id": "gid://shopify/SellingPlan/1",
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026",
"status": "active",
"created_at": "2026-06-25T10:30:45Z",
"updated_at": "2026-06-25T11:45:30Z",
"variants": {
"count": 3,
"url": "/api/v2/external/preorders/offers/1/products/variants"
},
"products": {
"source": "custom",
"custom": {
"variant_ids_sample": [
47284734423096,
47284734455864,
47284734488632
]
}
},
"widget": {
"button": {
"text": "Preorder Now",
"colors": {
"enabled": true,
"text_color": "#FFFFFF",
"background_color": "#1a1a1a"
}
},
"disclaimer": {
"enabled": true,
"text": "Expected to ship by August 2026",
"text_color": "#666666",
"background_color": "#F5F5F5",
"border_radius": "4px"
},
"badge": {
"enabled": true,
"text": "Pre-Order",
"text_color": "#FFFFFF",
"background_color": "#FF6B35"
}
},
"shipping": {
"delivery": {
"applies_to_all_products": true,
"type": "on_date",
"days": null,
"date": "2026-08-15T00:00:00Z"
},
"display": {
"show_details": true,
"shipping_text": "Ships in August 2026",
"shipping_line_item_property_enabled": true
}
},
"payments": {
"mode": "full",
"discount": {
"type": null,
"value": null
},
"options": [
{
"type": "full",
"deposit_percent": null
}
]
},
"limits": {
"per_order": {
"min": 1,
"max": 5
},
"per_customer": {
"max": 2
},
"total": {
"max": 500,
"current_count": null
},
"display": {
"show_remaining": true,
"quantity_limit_text": "Only 500 available"
}
},
"checkout": {
"terms": {
"enabled": true,
"text": "I understand this is a pre-order and will ship in August",
"disable_button_until_acknowledged": true
},
"mixed_cart": {
"allowed": false,
"error_message": "Pre-orders cannot be mixed with regular items"
},
"order_tags": {
"tags": [
"preorder",
"summer-2026"
]
}
},
"inventory": {
"provider": "stoq",
"reservation": {
"timing": "on_sale"
},
"continue_selling": {
"enabled": true,
"auto_apply_to_new_variants": true
}
},
"markets": {
"enabled": false,
"applies_to_all_markets": false,
"market_ids": []
},
"countdown": {
"enabled": true,
"mode": "to_schedule_end",
"format": "d:h:m:s",
"text": "Offer ends in"
},
"integrations": {
"pos": {
"enabled": true,
"skip_inventory_check": false
},
"b2b": {
"enabled": false
}
},
"translations": {
"default_locale": "en",
"locales": [
"en",
"fr"
],
"fields": [
"widget.button.text"
],
"translations": {
"fr": {
"widget.button.text": "Pré-commander"
}
}
},
"advanced": {
"use_shopify_selling_plan": false,
"custom_css": ".preorder-badge { font-weight: bold; }"
}
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update top-level fields of a preorder offer.
Body
nameanyinternal_nameanyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}),
});
const data = await response.json();import requests
payload = {
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}', json=payload)
data = response.json(){
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Advanced
Read power-user settings for a preorder offer (line item properties, button text overrides, Shopify selling plan attachment).
Parameters
idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Advanced
Update advanced (power-user) settings on a preorder offer.
Note: Deep partial. Toggles and clears are done via this PATCH: the line-item-property toggles are line_item_properties.include_shipping_text, .include_payment_breakdown, and .include_acknowledgement (true/false each). button_text_overrides is deep-partial per state — send null to clear an override for one state, e.g. { "button_text_overrides": { "out_of_stock": null } } removes that override (the read shape still emits all three states, with null for unset). sending an empty string or null.
Body
line_item_propertiesanybutton_text_overridesanyuse_shopify_selling_plananyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced' \
-H 'Content-Type: application/json' \
-d '{
"line_item_properties": "string",
"button_text_overrides": "Preorder now",
"use_shopify_selling_plan": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"line_item_properties": "string",
"button_text_overrides": "Preorder now",
"use_shopify_selling_plan": "string"
}),
});
const data = await response.json();import requests
payload = {
"line_item_properties": "string",
"button_text_overrides": "Preorder now",
"use_shopify_selling_plan": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced', json=payload)
data = response.json(){
"line_item_properties": "string",
"button_text_overrides": "Preorder now",
"use_shopify_selling_plan": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Advanced Attach To Shopify Selling Plan
Re-attach the offer to a Shopify selling plan group (resume syncing).
Note: Refused while "Move preorder items to a separate order" is on (shipping fulfillment.split.type 'orders'): the Shopify purchase option can't be used with separate orders. Turn that off first.
Parameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/attach_to_shopify_selling_plan'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/attach_to_shopify_selling_plan', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/attach_to_shopify_selling_plan')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Advanced Detach From Shopify Selling Plan
Detach the offer from Shopify selling plan groups; Stoq continues to manage it via the storefront integration.
Note: Strongly discouraged for most merchants. Breaks Shopify-native integrations like checkout selling plan display and third-party subscription apps. Does not delete the existing Shopify selling plan group — it just stops syncing. Also resets what needs the purchase option: partial payment to full payment, the discount to none, and a Scheduled fulfillment status to On hold. The response lists them in also_changed.
Parameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/detach_from_shopify_selling_plan'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/detach_from_shopify_selling_plan', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/detach_from_shopify_selling_plan')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Advanced Set Custom Line Item Property
Set a free-text custom line item property added to every preorder cart line.
Body
textanyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_custom_line_item_property' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_custom_line_item_property', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "Preorder now"
}),
});
const data = await response.json();import requests
payload = {
"text": "Preorder now"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_custom_line_item_property', json=payload)
data = response.json(){
"text": "Preorder now"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout
Read checkout settings for a preorder offer.
Parameters
idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout
Update checkout settings on a preorder offer.
Note: Boolean toggles are set via this PATCH: terms.enabled, terms.disable_button_until_acknowledged, terms.include_in_line_item_properties, mixed_cart.allowed — this PATCH is how you turn these on/off, e.g. { terms: { enabled: true } } or { mixed_cart: { allowed: false } }.
Body
termsanymixed_cartanyorder_tagsanyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout' \
-H 'Content-Type: application/json' \
-d '{
"terms": "string",
"mixed_cart": "string",
"order_tags": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"terms": "string",
"mixed_cart": "string",
"order_tags": "string"
}),
});
const data = await response.json();import requests
payload = {
"terms": "string",
"mixed_cart": "string",
"order_tags": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout', json=payload)
data = response.json(){
"terms": "string",
"mixed_cart": "string",
"order_tags": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout Add Order Tag
Add a tag to the set applied to orders containing this offer.
Body
taganyrequiredParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/add_order_tag' \
-H 'Content-Type: application/json' \
-d '{
"tag": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/add_order_tag', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"tag": "string"
}),
});
const data = await response.json();import requests
payload = {
"tag": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/add_order_tag', json=payload)
data = response.json(){
"tag": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout Remove Order Tag
Remove a tag from the set applied to orders containing this offer.
Body
taganyrequiredParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/remove_order_tag' \
-H 'Content-Type: application/json' \
-d '{
"tag": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/remove_order_tag', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"tag": "string"
}),
});
const data = await response.json();import requests
payload = {
"tag": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/remove_order_tag', json=payload)
data = response.json(){
"tag": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout Set Mixed Cart Allowed
Allow or block carts that mix preorder and regular items.
Body
allowedbooleanrequiredParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_allowed' \
-H 'Content-Type: application/json' \
-d '{
"allowed": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_allowed', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"allowed": true
}),
});
const data = await response.json();import requests
payload = {
"allowed": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_allowed', json=payload)
data = response.json(){
"allowed": true
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout Set Mixed Cart Error Message
Set the error message shown when a blocked mixed cart reaches checkout.
Body
messageanyrequiredParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_error_message' \
-H 'Content-Type: application/json' \
-d '{
"message": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_error_message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"message": "string"
}),
});
const data = await response.json();import requests
payload = {
"message": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_error_message', json=payload)
data = response.json(){
"message": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout Set Terms Settings
Require (or stop requiring) customers to accept preorder terms, with optional button-lock and acceptance-timestamp recording.
Body
enabledbooleanrequireddisable_button_untilanyrecord_timestampanytimestamp_labelanyParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_settings' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"disable_button_until": "string",
"record_timestamp": "string",
"timestamp_label": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_settings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"disable_button_until": "string",
"record_timestamp": "string",
"timestamp_label": "Preorder now"
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"disable_button_until": "string",
"record_timestamp": "string",
"timestamp_label": "Preorder now"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_settings', json=payload)
data = response.json(){
"enabled": true,
"disable_button_until": "string",
"record_timestamp": "string",
"timestamp_label": "Preorder now"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Checkout Set Terms Text
Set the terms-acceptance text shown next to the checkbox.
Body
textanyrequiredParameters
idstringrequiredpathResponse
Success — the updated resource.
Accepted — async/bulk work was queued. Poll the returned job.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_text', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "Preorder now"
}),
});
const data = await response.json();import requests
payload = {
"text": "Preorder now"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_text', json=payload)
data = response.json(){
"text": "Preorder now"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Countdown
Read the countdown timer configuration for a preorder offer.
Parameters
idstringrequiredpathResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The resource does not exist for this shop, or the action path is not registered.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.
Authorization
ApiKeyAuthapiKey in headerSend your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.
