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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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.
Parameters
filteranyallpreorderback_in_stockquerysearchanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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; 40 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).
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_keyanyResponse
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; 40 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"
}'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"
}),
});
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"
}
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"
}{}{
"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, 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; 40 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 · 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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 stopped by plan limits (with blocked_reason).
Parameters
channelanyemailsmspushquerystatusanysentblockedqueryvariant_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; 40 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; 40 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, or email.
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; 40 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. Filter with shopify_product_id, shopify_variant_id, or overrides_only=true.
Parameters
shopify_product_idanyqueryshopify_variant_idanyqueryoverrides_onlyanyquerylimitanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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. Targets that STOQ has no product_variants row for are reported in unmatched rather than created. 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; 40 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; 40 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; 40 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 and the revenue recovered.
Parameters
fromanyquerytoanyqueryvariant_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; 40 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; 40 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; 40 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; 40 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).
Parameters
fromanyquerytoanyqueryvariant_idanyqueryproduct_idanyquerychannelanyquerygranularityanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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; 40 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 by back-in-stock demand (pending/total signups, last requested).
Parameters
fromanyquerytoanyqueryvariant_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; 40 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; 40 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).
Parameters
fromanyquerytoanyqueryvariant_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; 40 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; 40 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
High-level overview of back-in-stock activity over a date window.
Parameters
fromanyquerytoanyqueryvariant_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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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.
Note: Channel toggles are set via this PATCH: email.enabled, sms.enabled, push.enabled — e.g. { sms: { enabled: true } }. Enabling SMS for the first time triggers a restricted-content verification check; sends may be held until the shop is verified.
Body
emailanysmsanypushanyResponse
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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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).
Parameters
channelanyemailsmspushquerystatusanypendingnotifiedunsubscribedqueryvariant_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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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.
Parameters
statusanyallenableddisabledscheduledquerysortanycreated_at desccreated_at ascinternal_name ascinternal_name descpreorder_revenue descpreorder_revenue ascquerypageanyqueryper_pageanyquerysearchanyquerymarket_idsanyqueryResponse
Success — example response shown.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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).
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; 40 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.
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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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}/countdown'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Countdown
Update countdown timer settings on a preorder offer.
Note: Deep partial. countdown.enabled is toggled via this PATCH (enabled true/false); text is an alias for ends_text — both write the same column, and an explicit ends_text wins when both are sent.
Body
enabledanymodeanycustom_end_dateanycustom_start_dateanyformatanytextanystarts_textanyends_textanyunit_labelsanystyleanyParameters
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; 40 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}/countdown' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"mode": "string",
"custom_end_date": "2026-07-01T00:00:00Z",
"custom_start_date": "2026-07-01T00:00:00Z",
"format": "string",
"text": "Preorder now",
"starts_text": "Preorder now",
"ends_text": "Preorder now",
"unit_labels": "Preorder now",
"style": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"mode": "string",
"custom_end_date": "2026-07-01T00:00:00Z",
"custom_start_date": "2026-07-01T00:00:00Z",
"format": "string",
"text": "Preorder now",
"starts_text": "Preorder now",
"ends_text": "Preorder now",
"unit_labels": "Preorder now",
"style": "string"
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"mode": "string",
"custom_end_date": "2026-07-01T00:00:00Z",
"custom_start_date": "2026-07-01T00:00:00Z",
"format": "string",
"text": "Preorder now",
"starts_text": "Preorder now",
"ends_text": "Preorder now",
"unit_labels": "Preorder now",
"style": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown', json=payload)
data = response.json(){
"enabled": true,
"mode": "string",
"custom_end_date": "2026-07-01T00:00:00Z",
"custom_start_date": "2026-07-01T00:00:00Z",
"format": "string",
"text": "Preorder now",
"starts_text": "Preorder now",
"ends_text": "Preorder now",
"unit_labels": "Preorder now",
"style": "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"
]
}Countdown Set Custom End Date
Set the custom end date for the countdown timer.
Note: Has no visible effect unless mode is to_custom_date.
Body
dateanyrequiredParameters
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; 40 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}/countdown/set_custom_end_date' \
-H 'Content-Type: application/json' \
-d '{
"date": "2026-07-01T00:00:00Z"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_custom_end_date', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"date": "2026-07-01T00:00:00Z"
}),
});
const data = await response.json();import requests
payload = {
"date": "2026-07-01T00:00:00Z"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_custom_end_date', json=payload)
data = response.json(){
"date": "2026-07-01T00:00:00Z"
}{}{
"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 Set Ends Text
Set the text shown next to the countdown timer when the offer is closing.
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; 40 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}/countdown/set_ends_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_ends_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}/countdown/set_ends_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 Set Mode
Set the countdown source: 'to_schedule_end' (count down to the offer's scheduled end) or 'to_custom_date' (count down to a fixed date set via set_custom_end_date).
Body
modeanyto_schedule_endto_custom_daterequiredParameters
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; 40 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}/countdown/set_mode' \
-H 'Content-Type: application/json' \
-d '{
"mode": "to_schedule_end"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_mode', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"mode": "to_schedule_end"
}),
});
const data = await response.json();import requests
payload = {
"mode": "to_schedule_end"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_mode', json=payload)
data = response.json(){
"mode": "to_schedule_end"
}{}{
"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 Set Starts Text
Set the text shown before the countdown timer when the offer hasn't started yet.
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; 40 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}/countdown/set_starts_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_starts_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}/countdown/set_starts_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 Set Style
Set the countdown timer's visual style (type, colors, border radius).
Body
typeanytext_coloranybackground_coloranyborder_radiusanyParameters
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; 40 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}/countdown/set_style' \
-H 'Content-Type: application/json' \
-d '{
"type": "string",
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_style', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"type": "string",
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": "string"
}),
});
const data = await response.json();import requests
payload = {
"type": "string",
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_style', json=payload)
data = response.json(){
"type": "string",
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": "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"
]
}Countdown Set Unit Labels
Set the countdown timer unit labels (days, hours, minutes, seconds).
Body
daysanyhoursanyminutesanysecondsanyParameters
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; 40 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}/countdown/set_unit_labels' \
-H 'Content-Type: application/json' \
-d '{
"days": "string",
"hours": "string",
"minutes": "string",
"seconds": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_unit_labels', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"days": "string",
"hours": "string",
"minutes": "string",
"seconds": "string"
}),
});
const data = await response.json();import requests
payload = {
"days": "string",
"hours": "string",
"minutes": "string",
"seconds": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_unit_labels', json=payload)
data = response.json(){
"days": "string",
"hours": "string",
"minutes": "string",
"seconds": "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"
]
}Disable
Disable (pause) a preorder offer. Optionally flip attached variants' inventory policy back to DENY.
Note: Variants are left at their existing inventory policy unless update_inventory_policy: true is passed.
Body
update_inventory_policyanyvariant_idsanyParameters
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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}/disable' \
-H 'Content-Type: application/json' \
-d '{
"update_inventory_policy": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/disable', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"update_inventory_policy": true
}),
});
const data = await response.json();import requests
payload = {
"update_inventory_policy": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/disable', json=payload)
data = response.json(){
"update_inventory_policy": true
}{
"id": "gid://shopify/SellingPlan/1",
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026",
"status": "paused",
"updated_at": "2026-06-25T12:15:20Z",
"variants": {
"count": 3,
"url": "/api/v2/external/preorders/offers/1/products/variants"
}
}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Discard
Discard (soft-delete) a preorder offer.
Note: Recoverable via restore indefinitely. Discarded offers are never hard-deleted.
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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}/discard'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/discard', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/discard')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Enable
Enable a preorder offer. On a scheduled offer this starts it now instead of on its start date (the start date is cleared; an end date is kept), as the dashboard does. Optionally flip attached variants' inventory policy to CONTINUE.
Note: Variants are left at their existing inventory policy unless update_inventory_policy: true is passed. On a scheduled offer (start date in the future) enable starts the offer now: schedule.start is cleared, schedule.end is kept, and with no end date the schedule is removed. To keep the start date, do not call enable; the offer starts on its own.
Body
update_inventory_policyanyvariant_idsanyParameters
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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}/enable' \
-H 'Content-Type: application/json' \
-d '{
"update_inventory_policy": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/enable', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"update_inventory_policy": true
}),
});
const data = await response.json();import requests
payload = {
"update_inventory_policy": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/enable', json=payload)
data = response.json(){
"update_inventory_policy": true
}{
"id": "gid://shopify/SellingPlan/1",
"name": "Summer Sneaker Drop",
"internal_name": "summer-2026",
"status": "active",
"updated_at": "2026-06-25T11:45:30Z",
"variants": {
"count": 3,
"url": "/api/v2/external/preorders/offers/1/products/variants"
}
}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Integrations
Read integration settings for a preorder offer (POS, B2B).
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; 40 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}/integrations'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Integrations
Update integration settings on a preorder offer.
Note: Boolean toggles are set via this PATCH: pos.enabled, pos.skip_inventory_check, b2b.enabled — e.g. { pos: { enabled: false } } or { b2b: { enabled: true } }.
Body
posanyb2banyParameters
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; 40 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}/integrations' \
-H 'Content-Type: application/json' \
-d '{
"pos": "string",
"b2b": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"pos": "string",
"b2b": "string"
}),
});
const data = await response.json();import requests
payload = {
"pos": "string",
"b2b": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations', json=payload)
data = response.json(){
"pos": "string",
"b2b": "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"
]
}Integrations Set B2b Enabled
Allow or disallow B2B customers to place preorders on this offer.
Body
enabledbooleanrequiredParameters
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; 40 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}/integrations/set_b2b_enabled' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations/set_b2b_enabled', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true
}),
});
const data = await response.json();import requests
payload = {
"enabled": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations/set_b2b_enabled', json=payload)
data = response.json(){
"enabled": 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"
]
}Integrations Set Pos Enabled
Enable or disable selling preorders on Shopify POS, with optional inventory-check skipping.
Body
enabledbooleanrequiredskip_inventory_checkanyParameters
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; 40 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}/integrations/set_pos_enabled' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"skip_inventory_check": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations/set_pos_enabled', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"skip_inventory_check": "string"
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"skip_inventory_check": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/integrations/set_pos_enabled', json=payload)
data = response.json(){
"enabled": true,
"skip_inventory_check": "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"
]
}Inventory
Read the inventory 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; 40 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}/inventory'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Inventory
Update inventory settings on a preorder offer.
Note: Deep partial. provider 'stoq' = the offer shows the Preorder button only when the product is OUT OF STOCK (the 'Show Preorder when product is out of stock' mode; needs Shopify's 'Continue selling when out of stock' on the variants). provider 'shopify' = the button shows for IN-STOCK products (the 'Show Preorder for in-stock products' mode). Setting provider to 'shopify' will force product_variants_source to 'custom' via the model callback. Continue-selling is toggled via this PATCH: continue_selling.enabled and continue_selling.auto_apply_to_new_variants BOTH map to the single underlying inventory_policy_auto_enable flag — the auto-flip-on-attach intent (newly-attached variants get their Shopify inventory_policy flipped to CONTINUE). When both fields are present, auto_apply_to_new_variants wins. Neither field flips EXISTING variants — to flip variants that are already attached, use POST .../products/bulk_toggle_inventory_policy, or pass the update_inventory_policy flag to the offer lifecycle enable/disable actions.
Body
provideranystoqshopifyreservationobjectcontinue_sellingobjectParameters
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; 40 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}/inventory' \
-H 'Content-Type: application/json' \
-d '{
"continue_selling": {
"enabled": true,
"auto_apply_to_new_variants": true
}
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"continue_selling": {
"enabled": true,
"auto_apply_to_new_variants": true
}
}),
});
const data = await response.json();import requests
payload = {
"continue_selling": {
"enabled": True,
"auto_apply_to_new_variants": True
}
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory', json=payload)
data = response.json(){
"continue_selling": {
"enabled": true,
"auto_apply_to_new_variants": true
}
}{
"provider": "stoq",
"reservation": {
"timing": "on_sale"
},
"continue_selling": {
"enabled": true,
"auto_apply_to_new_variants": 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"
]
}Inventory Set Provider
Set the inventory provider for a preorder offer (stoq or shopify).
Body
provideranystoqshopifyrequiredParameters
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; 40 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}/inventory/set_provider' \
-H 'Content-Type: application/json' \
-d '{
"provider": "stoq"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory/set_provider', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"provider": "stoq"
}),
});
const data = await response.json();import requests
payload = {
"provider": "stoq"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory/set_provider', json=payload)
data = response.json(){
"provider": "stoq"
}{}{
"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"
]
}Inventory Set Reservation Timing
Set when inventory is reserved: on_sale (held at order time) or on_fulfillment.
Body
timinganyon_saleon_fulfillmentrequiredParameters
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; 40 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}/inventory/set_reservation_timing' \
-H 'Content-Type: application/json' \
-d '{
"timing": "on_sale"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory/set_reservation_timing', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"timing": "on_sale"
}),
});
const data = await response.json();import requests
payload = {
"timing": "on_sale"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/inventory/set_reservation_timing', json=payload)
data = response.json(){
"timing": "on_sale"
}{}{
"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"
]
}Limits
Read order quantity limits 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; 40 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}/limits'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Limits
Update quantity limits on a preorder offer.
Note: Deep partial. Toggles and clears are done via this PATCH: clear a limit by sending null — per_order.max: null removes the per-order cap; display.show_remaining (true/false) toggles the remaining-units display on the storefront. Order tags, the terms-acceptance requirement, and mixed-cart behavior live on the checkout capability instead (PATCH .../checkout), not here.
Body
per_orderanydisplayanyParameters
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; 40 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}/limits' \
-H 'Content-Type: application/json' \
-d '{
"per_order": "string",
"display": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"per_order": "string",
"display": "string"
}),
});
const data = await response.json();import requests
payload = {
"per_order": "string",
"display": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits', json=payload)
data = response.json(){
"per_order": "string",
"display": "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"
]
}Limits Set Icons Enabled
Show or hide icons next to the quantity and shipping details on the widget.
Body
enabledbooleanrequiredParameters
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; 40 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}/limits/set_icons_enabled' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_icons_enabled', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true
}),
});
const data = await response.json();import requests
payload = {
"enabled": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_icons_enabled', json=payload)
data = response.json(){
"enabled": 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"
]
}Limits Set Max Per Order
Set the maximum quantity a customer can preorder per order.
Body
maxanyParameters
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; 40 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}/limits/set_max_per_order' \
-H 'Content-Type: application/json' \
-d '{
"max": 5
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_max_per_order', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"max": 5
}),
});
const data = await response.json();import requests
payload = {
"max": 5
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_max_per_order', json=payload)
data = response.json(){
"max": 5
}{}{
"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"
]
}Limits Set Min Per Order
Set the minimum quantity a customer must preorder per order.
Body
minanyParameters
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; 40 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}/limits/set_min_per_order' \
-H 'Content-Type: application/json' \
-d '{
"min": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_min_per_order', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"min": "string"
}),
});
const data = await response.json();import requests
payload = {
"min": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_min_per_order', json=payload)
data = response.json(){
"min": "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"
]
}Limits Set Progress Bar
Show or hide the preorder limit as a progress bar / counter on the widget, with optional text and colors.
Note: Enabling switches the limit display to the bar (disclaimer display off, like the editor radio). Colors are hex strings; show_percentage adds the percent label.
Body
enabledbooleanrequiredtextanyshow_percentageanyfill_coloranybackground_coloranybox_background_coloranytext_coloranyParameters
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; 40 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}/limits/set_progress_bar' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"text": "Preorder now",
"show_percentage": 25,
"fill_color": "#1A1A1A",
"background_color": "#1A1A1A",
"box_background_color": "#1A1A1A",
"text_color": "#1A1A1A"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_progress_bar', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"text": "Preorder now",
"show_percentage": 25,
"fill_color": "#1A1A1A",
"background_color": "#1A1A1A",
"box_background_color": "#1A1A1A",
"text_color": "#1A1A1A"
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"text": "Preorder now",
"show_percentage": 25,
"fill_color": "#1A1A1A",
"background_color": "#1A1A1A",
"box_background_color": "#1A1A1A",
"text_color": "#1A1A1A"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_progress_bar', json=payload)
data = response.json(){
"enabled": true,
"text": "Preorder now",
"show_percentage": 25,
"fill_color": "#1A1A1A",
"background_color": "#1A1A1A",
"box_background_color": "#1A1A1A",
"text_color": "#1A1A1A"
}{}{
"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"
]
}Limits Set Quantity Limit Text
Set the text shown with the preorder quantity limit on the widget.
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; 40 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}/limits/set_quantity_limit_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_quantity_limit_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}/limits/set_quantity_limit_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"
]
}Markets
Read market scoping 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; 40 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}/markets'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Markets
Update market scoping on a preorder offer.
Note: Deep partial. Scoping is toggled via this PATCH: enabled (true/false). The offer applies to ALL markets when scoping is off ({ "enabled": false }) or when scoping is on with an empty market list — the serializer compiles applies_to_all_markets from exactly that state. PATCH bodies: all markets → { "enabled": true, "market_ids": [] } (or { "enabled": true, "applies_to_all_markets": true }, which also clears the list); specific markets → { "enabled": true, "market_ids": ["gid://shopify/Market/1", ...] } (GIDs or numeric IDs). For incremental edits keep using add_market / remove_market / set_markets.
Body
enabledanyapplies_to_all_marketsanymarket_idsanyParameters
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; 40 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}/markets' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"applies_to_all_markets": "gid://shopify/Market/12345",
"market_ids": [
"gid://shopify/Market/12345"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"applies_to_all_markets": "gid://shopify/Market/12345",
"market_ids": [
"gid://shopify/Market/12345"
]
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"applies_to_all_markets": "gid://shopify/Market/12345",
"market_ids": [
"gid://shopify/Market/12345"
]
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets', json=payload)
data = response.json(){
"enabled": true,
"applies_to_all_markets": "gid://shopify/Market/12345",
"market_ids": [
"gid://shopify/Market/12345"
]
}{}{
"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"
]
}Markets Add Market
Add a market to the preorder offer's scope.
Body
market_idanyrequiredParameters
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; 40 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}/markets/add_market' \
-H 'Content-Type: application/json' \
-d '{
"market_id": "gid://shopify/Market/12345"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets/add_market', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"market_id": "gid://shopify/Market/12345"
}),
});
const data = await response.json();import requests
payload = {
"market_id": "gid://shopify/Market/12345"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets/add_market', json=payload)
data = response.json(){
"market_id": "gid://shopify/Market/12345"
}{}{
"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"
]
}Markets Remove Market
Remove a market from the preorder offer's scope.
Body
market_idanyrequiredParameters
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; 40 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}/markets/remove_market' \
-H 'Content-Type: application/json' \
-d '{
"market_id": "gid://shopify/Market/12345"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets/remove_market', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"market_id": "gid://shopify/Market/12345"
}),
});
const data = await response.json();import requests
payload = {
"market_id": "gid://shopify/Market/12345"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets/remove_market', json=payload)
data = response.json(){
"market_id": "gid://shopify/Market/12345"
}{}{
"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"
]
}Markets Set Markets
Replace the set of markets a preorder offer applies to.
Body
market_idsanyParameters
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; 40 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}/markets/set_markets' \
-H 'Content-Type: application/json' \
-d '{
"market_ids": [
"gid://shopify/Market/12345"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets/set_markets', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"market_ids": [
"gid://shopify/Market/12345"
]
}),
});
const data = await response.json();import requests
payload = {
"market_ids": [
"gid://shopify/Market/12345"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/markets/set_markets', json=payload)
data = response.json(){
"market_ids": [
"gid://shopify/Market/12345"
]
}{}{
"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"
]
}Payments
Read the payment 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; 40 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}/payments'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Payments
Update payment settings on a preorder offer.
Note: Use SetOptionCopy / EnableOption / DisableOption to edit individual payment options. Boolean toggles are set via this PATCH: remaining_balance.auto_collect, remaining_balance.auto_collect_on_fulfillment — mutually exclusive, e.g. { remaining_balance: { auto_collect: false } }. Clear the discount via { discount: { type: "no_discount" } } (the stored value is nulled automatically).
Body
discountanyremaining_balanceanyParameters
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; 40 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}/payments' \
-H 'Content-Type: application/json' \
-d '{
"discount": 5,
"remaining_balance": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"discount": 5,
"remaining_balance": "string"
}),
});
const data = await response.json();import requests
payload = {
"discount": 5,
"remaining_balance": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments', json=payload)
data = response.json(){
"discount": 5,
"remaining_balance": "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"
]
}Payments Disable Option
Remove a payment option (full or partial) from the offer.
Note: Only valid on full_and_partial offers — an offer must keep at least one payment option. Use set_mode to switch a single-mode offer.
Body
option_typeanyfullpartialrequiredParameters
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; 40 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}/payments/disable_option' \
-H 'Content-Type: application/json' \
-d '{
"option_type": "full"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/disable_option', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"option_type": "full"
}),
});
const data = await response.json();import requests
payload = {
"option_type": "full"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/disable_option', json=payload)
data = response.json(){
"option_type": "full"
}{}{
"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"
]
}Payments Enable Option
Add a payment option (full or partial) to the offer.
Note: Idempotent. Newly added options start from the dashboard defaults — use set_deposit_percent / set_option_copy to fine-tune. Disable with disable_option.
Body
option_typeanyfullpartialrequiredParameters
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; 40 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}/payments/enable_option' \
-H 'Content-Type: application/json' \
-d '{
"option_type": "full"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/enable_option', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"option_type": "full"
}),
});
const data = await response.json();import requests
payload = {
"option_type": "full"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/enable_option', json=payload)
data = response.json(){
"option_type": "full"
}{}{
"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"
]
}Payments Set Balance Due Days
Charge the remaining preorder balance a number of days after checkout.
Note: Switches the offer to the 'time after checkout' remaining-balance mode and charges the balance days days after checkout. days must be a whole number >= 1. Use set_payment_date instead to charge on a specific calendar date, or the payments PATCH to toggle auto-collect.
Body
daysinteger>= 1requiredParameters
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; 40 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}/payments/set_balance_due_days' \
-H 'Content-Type: application/json' \
-d '{
"days": 1
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_balance_due_days', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"days": 1
}),
});
const data = await response.json();import requests
payload = {
"days": 1
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_balance_due_days', json=payload)
data = response.json(){
"days": 1
}{}{
"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"
]
}Payments Set Billing Widget
Show or hide the payment & discount savings widget in the purchase flow.
Note: Toggles the storefront widget that shows the customer their payment schedule and discount savings at every step of the purchase flow. enabled must be true or false.
Body
enabledbooleanrequiredParameters
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; 40 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}/payments/set_billing_widget' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_billing_widget', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true
}),
});
const data = await response.json();import requests
payload = {
"enabled": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_billing_widget', json=payload)
data = response.json(){
"enabled": 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"
]
}Payments Set Deposit Amount
Set a fixed deposit amount charged at checkout on the partial payment option.
Note: Requires a partial payment option (mode partial or full_and_partial) -- use set_mode first. amount is in the store currency and must be more than 0. For a percent deposit use set_deposit_percent.
Body
amountnumberrequiredParameters
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; 40 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}/payments/set_deposit_amount' \
-H 'Content-Type: application/json' \
-d '{
"amount": 1
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_deposit_amount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"amount": 1
}),
});
const data = await response.json();import requests
payload = {
"amount": 1
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_deposit_amount', json=payload)
data = response.json(){
"amount": 1
}{}{
"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"
]
}Payments Set Deposit Percent
Set the deposit percentage charged at checkout on the partial payment option.
Note: Requires a partial payment option (mode partial or full_and_partial) — use set_mode first. Percent must be between 1 and 99; 100% upfront is the full payment mode.
Body
percentinteger[1, 99]requiredParameters
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; 40 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}/payments/set_deposit_percent' \
-H 'Content-Type: application/json' \
-d '{
"percent": 25
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_deposit_percent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"percent": 25
}),
});
const data = await response.json();import requests
payload = {
"percent": 25
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_deposit_percent', json=payload)
data = response.json(){
"percent": 25
}{}{
"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"
]
}Payments Set Discount
Set the preorder discount. type is one of: percentage, price, fixed_amount, no_discount; value is the amount (omit for no_discount).
Body
typeanypercentagepricefixed_amountno_discountrequiredvalueanyParameters
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; 40 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}/payments/set_discount' \
-H 'Content-Type: application/json' \
-d '{
"type": "percentage",
"value": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_discount', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"type": "percentage",
"value": "string"
}),
});
const data = await response.json();import requests
payload = {
"type": "percentage",
"value": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_discount', json=payload)
data = response.json(){
"type": "percentage",
"value": "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"
]
}Payments Set Discount Text
Set the discount blurb shown on the offer's payment options. option_type (optional) must be either full or partial.
Note: Pass option_type (full | partial) to target one payment option; omit it to apply the text to every option. Supports the {{ discount }} placeholder.
Body
textanyrequiredoption_typeanyfullpartialParameters
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; 40 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}/payments/set_discount_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now",
"option_type": "full"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_discount_text', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "Preorder now",
"option_type": "full"
}),
});
const data = await response.json();import requests
payload = {
"text": "Preorder now",
"option_type": "full"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_discount_text', json=payload)
data = response.json(){
"text": "Preorder now",
"option_type": "full"
}{}{
"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"
]
}Payments Set Mode
Switch the offer's payment mode. mode must be exactly one of: full, partial, full_and_partial.
Note: Idempotent. Collapsing from full_and_partial keeps the surviving option's copy; newly enabled modes start from the dashboard defaults. Use set_deposit_percent and set_option_copy afterwards to fine-tune.
Body
modeanyfullpartialfull_and_partialrequiredParameters
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; 40 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}/payments/set_mode' \
-H 'Content-Type: application/json' \
-d '{
"mode": "full"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_mode', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"mode": "full"
}),
});
const data = await response.json();import requests
payload = {
"mode": "full"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_mode', json=payload)
data = response.json(){
"mode": "full"
}{}{
"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"
]
}Payments Set Option Copy
Set the merchant-facing copy on a payment option (title, description, discount text). option_type must be either full or partial.
Body
option_typeanyfullpartialrequiredbilling_titleanybilling_descriptionanydiscount_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; 40 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}/payments/set_option_copy' \
-H 'Content-Type: application/json' \
-d '{
"option_type": "full",
"billing_title": "string",
"billing_description": "string",
"discount_text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_option_copy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"option_type": "full",
"billing_title": "string",
"billing_description": "string",
"discount_text": "Preorder now"
}),
});
const data = await response.json();import requests
payload = {
"option_type": "full",
"billing_title": "string",
"billing_description": "string",
"discount_text": "Preorder now"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_option_copy', json=payload)
data = response.json(){
"option_type": "full",
"billing_title": "string",
"billing_description": "string",
"discount_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"
]
}Payments Set Payment Date
Set the exact date the remaining preorder balance is charged.
Body
dateanyrequiredParameters
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; 40 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}/payments/set_payment_date' \
-H 'Content-Type: application/json' \
-d '{
"date": "2026-07-01T00:00:00Z"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_payment_date', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"date": "2026-07-01T00:00:00Z"
}),
});
const data = await response.json();import requests
payload = {
"date": "2026-07-01T00:00:00Z"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_payment_date', json=payload)
data = response.json(){
"date": "2026-07-01T00:00:00Z"
}{}{
"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"
]
}Payments Set Show Discounted Price
Show or hide the discounted preorder price on the widget.
Body
enabledbooleanrequiredParameters
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; 40 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}/payments/set_show_discounted_price' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_show_discounted_price', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true
}),
});
const data = await response.json();import requests
payload = {
"enabled": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/payments/set_show_discounted_price', json=payload)
data = response.json(){
"enabled": 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"
]
}Products
Read the products configuration for a preorder offer (source rule + variant summary).
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; 40 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}/products'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Products
Update the product selection on a preorder offer — set the source rule plus its matching sub-block. source must be exactly one of: all, collection, custom.
Note: Delegates to the set_source_to_* actions; switching source resets the variant set. source 'all' requires confirm: true. Only the sub-block matching source may be provided.
Body
sourceanyallcollectioncustomrequiredcustomobject | nullcollectionobject | nullallobject | nullconfirmanyParameters
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; 40 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}/products' \
-H 'Content-Type: application/json' \
-d '{
"source": "all",
"custom": "string",
"collection": "string",
"all": "string",
"confirm": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"source": "all",
"custom": "string",
"collection": "string",
"all": "string",
"confirm": "string"
}),
});
const data = await response.json();import requests
payload = {
"source": "all",
"custom": "string",
"collection": "string",
"all": "string",
"confirm": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products', json=payload)
data = response.json(){
"source": "all",
"custom": "string",
"collection": "string",
"all": "string",
"confirm": "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"
]
}Products Add Variants
Attach variants to a custom-source preorder offer.
Note: Custom source only. Idempotent: already-attached variants are skipped and reported under already_present. Runs through BulkVariantAdditionService (async).
Body
variant_idsanyParameters
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; 40 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}/products/add_variants' \
-H 'Content-Type: application/json' \
-d '{
"variant_ids": [
47284734423096,
47284734455864,
47284734488632
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/add_variants', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"variant_ids": [
47284734423096,
47284734455864,
47284734488632
]
}),
});
const data = await response.json();import requests
payload = {
"variant_ids": [
47284734423096,
47284734455864,
47284734488632
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/add_variants', json=payload)
data = response.json(){
"variant_ids": [
47284734423096,
47284734455864,
47284734488632
]
}{
"source": "custom",
"variants": {
"count": 6,
"url": "/api/v2/external/preorders/offers/1/products/variants"
},
"custom": {
"variant_ids_sample": [
47284734423096,
47284734455864,
47284734488632,
47284734521400,
47284734554168,
47284734586936
]
}
}{
"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"
]
}Products Bulk Toggle Inventory Policy
Flip the Shopify inventory policy on variants attached to a preorder offer (CONTINUE or DENY). Pass the explicit variant_ids for a partial change; omitting variant_ids applies the policy to EVERY attached variant, so only omit it when the merchant asked for all of them.
Note: Async via SellingPlans::BulkInventoryPolicyUpdateJob. Omit variant_ids to apply to all attached variants.
Body
policyanyCONTINUEDENYrequiredvariant_idsanyParameters
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; 40 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}/products/bulk_toggle_inventory_policy' \
-H 'Content-Type: application/json' \
-d '{
"policy": "CONTINUE",
"variant_ids": [
"45000000001"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/bulk_toggle_inventory_policy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"policy": "CONTINUE",
"variant_ids": [
"45000000001"
]
}),
});
const data = await response.json();import requests
payload = {
"policy": "CONTINUE",
"variant_ids": [
"45000000001"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/bulk_toggle_inventory_policy', json=payload)
data = response.json(){
"policy": "CONTINUE",
"variant_ids": [
"45000000001"
]
}{}{
"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"
]
}Products Remove Variants
Remove variants from a custom-source preorder offer.
Note: Custom source only. Resets per-variant metafields on Shopify.
Body
variant_idsanyParameters
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; 40 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}/products/remove_variants' \
-H 'Content-Type: application/json' \
-d '{
"variant_ids": [
"45000000001"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/remove_variants', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"variant_ids": [
"45000000001"
]
}),
});
const data = await response.json();import requests
payload = {
"variant_ids": [
"45000000001"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/remove_variants', json=payload)
data = response.json(){
"variant_ids": [
"45000000001"
]
}{}{
"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"
]
}Products Set Collection
Change the collection driving a collection-sourced preorder offer.
Note: Collection-sourced offers only — returns 409 Conflict otherwise. Use set_source_to_collection to switch a non-collection offer to collection source.
Body
collection_idanyrequiredParameters
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; 40 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}/products/set_collection' \
-H 'Content-Type: application/json' \
-d '{
"collection_id": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_collection', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"collection_id": "string"
}),
});
const data = await response.json();import requests
payload = {
"collection_id": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_collection', json=payload)
data = response.json(){
"collection_id": "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"
]
}Products Set Excluded Variants
Replace the explicit excluded-variant list for an all-source preorder offer.
Note: All-source offers only.
Body
variant_idsanyParameters
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; 40 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}/products/set_excluded_variants' \
-H 'Content-Type: application/json' \
-d '{
"variant_ids": [
"45000000001"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_excluded_variants', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"variant_ids": [
"45000000001"
]
}),
});
const data = await response.json();import requests
payload = {
"variant_ids": [
"45000000001"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_excluded_variants', json=payload)
data = response.json(){
"variant_ids": [
"45000000001"
]
}{}{
"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"
]
}Products Set Exclusion Tag
Set the exclusion tag for an all-source preorder offer (variants with this tag are excluded).
Note: All-source offers only.
Body
taganyParameters
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; 40 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}/products/set_exclusion_tag' \
-H 'Content-Type: application/json' \
-d '{
"tag": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_exclusion_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}/products/set_exclusion_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"
]
}Products Set Source To All
Switch the offer to apply to every variant in the shop, minus exclusions. Requires confirm: true.
Note: Requires confirm: true in the body. Resolution runs async over the entire catalog.
Body
confirmanyexclusion_taganyexcluded_variant_idsanyParameters
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; 40 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}/products/set_source_to_all' \
-H 'Content-Type: application/json' \
-d '{
"confirm": "string",
"exclusion_tag": "string",
"excluded_variant_ids": [
"string"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_source_to_all', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"confirm": "string",
"exclusion_tag": "string",
"excluded_variant_ids": [
"string"
]
}),
});
const data = await response.json();import requests
payload = {
"confirm": "string",
"exclusion_tag": "string",
"excluded_variant_ids": [
"string"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_source_to_all', json=payload)
data = response.json(){
"confirm": "string",
"exclusion_tag": "string",
"excluded_variant_ids": [
"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"
]
}Products Set Source To Collection
Switch the offer to a collection-driven variant source.
Note: Resolution runs asynchronously. New variants added to the collection in Shopify are NOT auto-picked-up — call this action again to refresh.
Body
collection_idanyrequiredParameters
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; 40 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}/products/set_source_to_collection' \
-H 'Content-Type: application/json' \
-d '{
"collection_id": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_source_to_collection', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"collection_id": "string"
}),
});
const data = await response.json();import requests
payload = {
"collection_id": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_source_to_collection', json=payload)
data = response.json(){
"collection_id": "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"
]
}Products Set Source To Custom
Switch the offer to a custom variant list. Optionally seed it with variant IDs.
Note: Variant attachment runs through BulkVariantAdditionService and is async (202 + job_id).
Body
variant_idsanyParameters
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; 40 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}/products/set_source_to_custom' \
-H 'Content-Type: application/json' \
-d '{
"variant_ids": [
"45000000001"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_source_to_custom', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"variant_ids": [
"45000000001"
]
}),
});
const data = await response.json();import requests
payload = {
"variant_ids": [
"45000000001"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/set_source_to_custom', json=payload)
data = response.json(){
"variant_ids": [
"45000000001"
]
}{}{
"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"
]
}Products Variants
List the variants attached to a preorder offer with their per-variant settings, paginated.
Parameters
idstringrequiredpathpageanyqueryper_pageanyqueryResponse
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; 40 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}/products/variants'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Products Variants
Read the per-offer settings of a single variant attached to a preorder offer.
Parameters
idstringrequiredpathvariant_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; 40 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}/products/variants/{variant_id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants/{variant_id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants/{variant_id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Products Variants
Set per-offer overrides on an attached variant — shipping text and max preorder count.
Note: null clears an override; the variant falls back to the offer-level value. market_overrides is no longer accepted; set per-market values on the offer instead.
Body
shipping_textstring | nullmax_countinteger | nullParameters
idstringrequiredpathvariant_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; 40 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}/products/variants/{variant_id}' \
-H 'Content-Type: application/json' \
-d '{
"shipping_text": "Preorder now",
"max_count": 5
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants/{variant_id}', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"shipping_text": "Preorder now",
"max_count": 5
}),
});
const data = await response.json();import requests
payload = {
"shipping_text": "Preorder now",
"max_count": 5
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants/{variant_id}', json=payload)
data = response.json(){
"shipping_text": "Preorder now",
"max_count": 5
}{}{
"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"
]
}Products Variants Toggle Inventory Policy
Set whether Shopify continues selling one attached preorder variant when it is out of stock (CONTINUE or DENY).
Note: Delegates asynchronously to BulkToggleInventoryPolicy with this single variant ID.
Body
policyanyCONTINUEDENYrequiredParameters
idstringrequiredpathvariant_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; 40 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}/products/variants/{variant_id}/toggle_inventory_policy' \
-H 'Content-Type: application/json' \
-d '{
"policy": "CONTINUE"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants/{variant_id}/toggle_inventory_policy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"policy": "CONTINUE"
}),
});
const data = await response.json();import requests
payload = {
"policy": "CONTINUE"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/products/variants/{variant_id}/toggle_inventory_policy', json=payload)
data = response.json(){
"policy": "CONTINUE"
}{}{
"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"
]
}Rename
Rename a preorder offer (customer-facing name and/or internal label).
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; 40 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}/rename' \
-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}/rename', {
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/{id}/rename', 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"
]
}Restore
Restore a discarded preorder offer.
Note: Variant attachments and metafields are not auto-restored. Re-attach via the products capability.
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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}/restore'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/restore', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/restore')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Schedule
Set the schedule window for a preorder offer.
Note: Does not auto-enable. Storefront reads the schedule live.
Body
startanyendanyParameters
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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}/schedule' \
-H 'Content-Type: application/json' \
-d '{
"start": "2026-07-01T00:00:00Z",
"end": "2026-07-01T00:00:00Z"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/schedule', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"start": "2026-07-01T00:00:00Z",
"end": "2026-07-01T00:00:00Z"
}),
});
const data = await response.json();import requests
payload = {
"start": "2026-07-01T00:00:00Z",
"end": "2026-07-01T00:00:00Z"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/schedule', json=payload)
data = response.json(){
"start": "2026-07-01T00:00:00Z",
"end": "2026-07-01T00:00:00Z"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Shipping
Read shipping 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; 40 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}/shipping'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Shipping
Update shipping settings on a preorder offer.
Note: Deep partial. Prefer the intent-bearing actions (set_delivery_*, set_shipping_text, set_split_order_tag, set_split_order_suffix, set_split_transaction_gateway) for narrow edits. Toggles are done via this PATCH: fulfillment.hold (true/false) holds/releases fulfillment orders containing preorder items -- mutually exclusive with fulfillment.split, cannot both be on; fulfillment.split.type ('fulfillments' or 'orders') picks which split behavior is on -- these are two distinct settings, not one, and mutually exclusive with fulfillment.hold; 'fulfillments' also requires delivery.type to be (or become, in the same request) 'asap'; fulfillment.split.enabled (true/false) is a legacy toggle: true requires type to also be set, false clears both; fulfillment.split.hold_fulfillments (true/false) holds the split order's fulfillments; fulfillment.split.sequential_number (true/false) gives split orders a sequential order name.
Body
deliveryanydisplayanyfulfillmentanyParameters
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; 40 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}/shipping' \
-H 'Content-Type: application/json' \
-d '{
"delivery": "string",
"display": "string",
"fulfillment": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"delivery": "string",
"display": "string",
"fulfillment": "string"
}),
});
const data = await response.json();import requests
payload = {
"delivery": "string",
"display": "string",
"fulfillment": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping', json=payload)
data = response.json(){
"delivery": "string",
"display": "string",
"fulfillment": "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"
]
}Shipping Set Auto Release Holds
Enable or disable automatic release of fulfillment holds, with an optional release date and pay-first requirement.
Note: date sets when holds release; require_payment: true waits for the balance to be collected first. Disabling clears the stored release date.
Body
enabledbooleanrequireddateanyrequire_paymentanyParameters
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; 40 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}/shipping/set_auto_release_holds' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"date": "2026-07-01T00:00:00Z",
"require_payment": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_auto_release_holds', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"date": "2026-07-01T00:00:00Z",
"require_payment": "string"
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"date": "2026-07-01T00:00:00Z",
"require_payment": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_auto_release_holds', json=payload)
data = response.json(){
"enabled": true,
"date": "2026-07-01T00:00:00Z",
"require_payment": "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"
]
}Shipping Set Delivery Asap
Set delivery to 'as soon as possible' (no specific date or window).
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; 40 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}/shipping/set_delivery_asap'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_delivery_asap', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_delivery_asap')
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"
]
}Shipping Set Delivery Date
Set an exact delivery date for the preorder.
Body
dateanyrequiredParameters
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; 40 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}/shipping/set_delivery_date' \
-H 'Content-Type: application/json' \
-d '{
"date": "2026-07-01T00:00:00Z"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_delivery_date', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"date": "2026-07-01T00:00:00Z"
}),
});
const data = await response.json();import requests
payload = {
"date": "2026-07-01T00:00:00Z"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_delivery_date', json=payload)
data = response.json(){
"date": "2026-07-01T00:00:00Z"
}{}{
"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"
]
}Shipping Set Delivery Window
Set a delivery window in days from checkout (e.g. 'ships within 14 days').
Body
daysanyParameters
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; 40 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}/shipping/set_delivery_window' \
-H 'Content-Type: application/json' \
-d '{
"days": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_delivery_window', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"days": "string"
}),
});
const data = await response.json();import requests
payload = {
"days": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_delivery_window', json=payload)
data = response.json(){
"days": "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"
]
}Shipping Set Hold Fulfillments
Hold (or release) all fulfillments for preorders on this offer, with an optional reason note.
Body
enabledbooleanrequiredreason_noteanyParameters
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; 40 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}/shipping/set_hold_fulfillments' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"reason_note": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_hold_fulfillments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true,
"reason_note": "string"
}),
});
const data = await response.json();import requests
payload = {
"enabled": True,
"reason_note": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_hold_fulfillments', json=payload)
data = response.json(){
"enabled": true,
"reason_note": "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"
]
}Shipping Set Shipping Text
Set the customer-facing shipping text shown on the PDP.
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; 40 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}/shipping/set_shipping_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_shipping_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}/shipping/set_shipping_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"
]
}Shipping Set Split Order Suffix
Set the suffix appended to the original order name for split orders (e.g. #1001-SPLIT).
Body
suffixanyrequiredParameters
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; 40 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}/shipping/set_split_order_suffix' \
-H 'Content-Type: application/json' \
-d '{
"suffix": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_split_order_suffix', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"suffix": "string"
}),
});
const data = await response.json();import requests
payload = {
"suffix": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_split_order_suffix', json=payload)
data = response.json(){
"suffix": "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"
]
}Shipping Set Split Order Tag
Set the tag applied to split orders on Shopify.
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; 40 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}/shipping/set_split_order_tag' \
-H 'Content-Type: application/json' \
-d '{
"tag": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_split_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}/shipping/set_split_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"
]
}Shipping Set Split Transaction Gateway
Set the payment gateway used for the split order transaction (e.g. 'Prepaid').
Body
gatewayanyrequiredParameters
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; 40 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}/shipping/set_split_transaction_gateway' \
-H 'Content-Type: application/json' \
-d '{
"gateway": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_split_transaction_gateway', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"gateway": "string"
}),
});
const data = await response.json();import requests
payload = {
"gateway": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/shipping/set_split_transaction_gateway', json=payload)
data = response.json(){
"gateway": "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"
]
}Translations
Read every translation override on a preorder offer, plus the full enumeration of translatable field paths, each field's default-locale source text, and every locale the shop has actually published (not just ones with an override already).
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; 40 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}/translations'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Translations Clear Locale
Remove all translation overrides for one locale on a preorder offer.
Body
localeanyrequiredParameters
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; 40 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}/translations/clear_locale' \
-H 'Content-Type: application/json' \
-d '{
"locale": "fr"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/clear_locale', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"locale": "fr"
}),
});
const data = await response.json();import requests
payload = {
"locale": "fr"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/clear_locale', json=payload)
data = response.json(){
"locale": "fr"
}{}{
"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"
]
}Translations Set
Set a single translation override (one locale, one field) on a preorder offer.
Body
localeanyrequiredfieldanyrequiredvalueanyParameters
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; 40 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}/translations/set' \
-H 'Content-Type: application/json' \
-d '{
"locale": "fr",
"field": "string",
"value": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/set', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"locale": "fr",
"field": "string",
"value": "string"
}),
});
const data = await response.json();import requests
payload = {
"locale": "fr",
"field": "string",
"value": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/set', json=payload)
data = response.json(){
"locale": "fr",
"field": "string",
"value": "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"
]
}Translations Set Many
Set many translation overrides for one locale on a preorder offer, atomically.
Note: All-or-nothing. Pre-validates every field path before writing.
Body
localeanyrequiredtranslationsanyrequiredParameters
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; 40 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}/translations/set_many' \
-H 'Content-Type: application/json' \
-d '{
"locale": "fr",
"translations": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/set_many', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"locale": "fr",
"translations": "string"
}),
});
const data = await response.json();import requests
payload = {
"locale": "fr",
"translations": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/set_many', json=payload)
data = response.json(){
"locale": "fr",
"translations": "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"
]
}Translations Unset
Remove a translation override (one locale, one field) from a preorder offer.
Body
localeanyrequiredfieldanyrequiredParameters
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; 40 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}/translations/unset' \
-H 'Content-Type: application/json' \
-d '{
"locale": "fr",
"field": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/unset', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"locale": "fr",
"field": "string"
}),
});
const data = await response.json();import requests
payload = {
"locale": "fr",
"field": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/translations/unset', json=payload)
data = response.json(){
"locale": "fr",
"field": "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"
]
}Unschedule
Clear the schedule window on a preorder offer.
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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}/unschedule'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/unschedule', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/unschedule')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Widget
Read the widget 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; 40 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}/widget'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Widget
Update any subset of the widget configuration on a preorder offer.
Note: Deep partial. Use the intent-bearing widget actions for narrow edits. Boolean toggles are set via this PATCH: badge.enabled, disclaimer.enabled, button.colors.enabled, billing_widget.enabled — e.g. { badge: { enabled: false } }. Clearing a value: send null.
Body
buttonanydisclaimeranybadgeanybilling_widgetanyParameters
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; 40 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}/widget' \
-H 'Content-Type: application/json' \
-d '{
"button": "string",
"disclaimer": "string",
"badge": "string",
"billing_widget": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"button": "string",
"disclaimer": "string",
"badge": "string",
"billing_widget": "string"
}),
});
const data = await response.json();import requests
payload = {
"button": "string",
"disclaimer": "string",
"badge": "string",
"billing_widget": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget', json=payload)
data = response.json(){
"button": "string",
"disclaimer": "string",
"badge": "string",
"billing_widget": "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"
]
}Widget Set Badge Colors
Set the preorder badge's text and background colors.
Body
text_coloranybackground_coloranyParameters
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; 40 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}/widget/set_badge_colors' \
-H 'Content-Type: application/json' \
-d '{
"text_color": "#1A1A1A",
"background_color": "#1A1A1A"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_badge_colors', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text_color": "#1A1A1A",
"background_color": "#1A1A1A"
}),
});
const data = await response.json();import requests
payload = {
"text_color": "#1A1A1A",
"background_color": "#1A1A1A"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_badge_colors', json=payload)
data = response.json(){
"text_color": "#1A1A1A",
"background_color": "#1A1A1A"
}{}{
"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"
]
}Widget Set Badge Enabled
Show or hide the preorder badge on the widget.
Body
enabledbooleanrequiredParameters
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; 40 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}/widget/set_badge_enabled' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_badge_enabled', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true
}),
});
const data = await response.json();import requests
payload = {
"enabled": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_badge_enabled', json=payload)
data = response.json(){
"enabled": 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"
]
}Widget Set Badge Text
Set the preorder badge text.
Note: Use set_badge_enabled to control visibility.
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; 40 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}/widget/set_badge_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_badge_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}/widget/set_badge_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"
]
}Widget Set Billing Widget Text
Set the billing widget's title and description (the PDP payment-breakdown block).
Note: These fields are shared with the first payment option's copy (see payments/set_option_copy). Use enable_billing_widget / disable_billing_widget to control visibility.
Body
titleanydescriptionanyParameters
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; 40 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}/widget/set_billing_widget_text' \
-H 'Content-Type: application/json' \
-d '{
"title": "string",
"description": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_billing_widget_text', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "string",
"description": "string"
}),
});
const data = await response.json();import requests
payload = {
"title": "string",
"description": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_billing_widget_text', json=payload)
data = response.json(){
"title": "string",
"description": "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"
]
}Widget Set Disclaimer Enabled
Show or hide the disclaimer line under the preorder button.
Body
enabledbooleanrequiredParameters
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; 40 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}/widget/set_disclaimer_enabled' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_disclaimer_enabled', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": true
}),
});
const data = await response.json();import requests
payload = {
"enabled": True
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_disclaimer_enabled', json=payload)
data = response.json(){
"enabled": 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"
]
}Widget Set Disclaimer Style
Set the disclaimer banner's colors and border radius.
Body
text_coloranybackground_coloranyborder_radiusinteger>= 0Parameters
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; 40 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}/widget/set_disclaimer_style' \
-H 'Content-Type: application/json' \
-d '{
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": 0
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_disclaimer_style', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": 0
}),
});
const data = await response.json();import requests
payload = {
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": 0
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_disclaimer_style', json=payload)
data = response.json(){
"text_color": "#1A1A1A",
"background_color": "#1A1A1A",
"border_radius": 0
}{}{
"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"
]
}Widget Set Disclaimer Text
Set the disclaimer banner text shown under the preorder button.
Note: Use enable_disclaimer / disable_disclaimer to control visibility.
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; 40 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}/widget/set_disclaimer_text' \
-H 'Content-Type: application/json' \
-d '{
"text": "Preorder now"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/widget/set_disclaimer_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}/widget/set_disclaimer_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"
]
}Preorders · Orders
List
List preorder orders in this shop, paginated. search matches order number/name, customer name, or email.
Parameters
pageanyqueryper_pageanyquerysearchanyquerystateanyqueryoffer_idanyqueryvariant_idanyquerycustomer_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; 40 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/orders'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/orders')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Read
Read a preorder order'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; 40 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/orders/{id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Cancel
Cancel a preorder. Optionally refund deposit / balance and notify the customer.
Note: Does not cancel the Shopify order; sets cancelled_at on the preorder attribution. Use the refund flags for refunds.
Body
refund_depositanyrefund_balanceanynotify_customeranyreasonanyParameters
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/orders/{id}/cancel' \
-H 'Content-Type: application/json' \
-d '{
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/cancel', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}),
});
const data = await response.json();import requests
payload = {
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/cancel', json=payload)
data = response.json(){
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Collect Payment
Collect the order's outstanding balance now by charging the customer's saved payment method.
Note: Matches the merchant dashboard action Collect payment. Charges the customer immediately; may fail when there is no saved payment method or the charge is declined — check the response. Set send_notifications false to suppress the customer email sent when a charge fails.
Body
send_notificationsanyParameters
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; 40 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/orders/{id}/collect_payment' \
-H 'Content-Type: application/json' \
-d '{
"send_notifications": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/collect_payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"send_notifications": "string"
}),
});
const data = await response.json();import requests
payload = {
"send_notifications": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/collect_payment', json=payload)
data = response.json(){
"send_notifications": "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"
]
}Fulfillment
Read the fulfillment hold state and fulfillment-order summary of a preorder order.
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; 40 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/orders/{id}/fulfillment'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Fulfillment
Update fulfillment attributes on a preorder order. Only hold_reason_note is writable.
Note: Hold state changes go through release_holds / apply_holds. all_held, any_held, and fulfillment_orders are read-only. Delegates to SetHoldReason; existing holds on Shopify aren't re-written.
Body
hold_reason_notestring | nullParameters
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; 40 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/orders/{id}/fulfillment' \
-H 'Content-Type: application/json' \
-d '{
"hold_reason_note": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"hold_reason_note": "string"
}),
});
const data = await response.json();import requests
payload = {
"hold_reason_note": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment', json=payload)
data = response.json(){
"hold_reason_note": "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"
]
}Fulfillment Apply Holds
Apply fulfillment holds on the order's fulfillment orders. Idempotent.
Body
reason_notestring | nullParameters
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; 40 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/orders/{id}/fulfillment/apply_holds' \
-H 'Content-Type: application/json' \
-d '{
"reason_note": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment/apply_holds', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"reason_note": "string"
}),
});
const data = await response.json();import requests
payload = {
"reason_note": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment/apply_holds', json=payload)
data = response.json(){
"reason_note": "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"
]
}Fulfillment Release Holds
Release fulfillment holds on the order without applying offer-configured tags.
Note: Use the top-level release action when you want tags applied too.
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; 40 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/orders/{id}/fulfillment/release_holds'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment/release_holds', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment/release_holds')
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"
]
}Fulfillment Set Hold Reason
Set the hold-reason note that will be used the next time the order is held.
Note: Updates the note on the first attributed preorder offer. Existing holds on Shopify aren't re-written.
Body
reason_noteanyrequiredParameters
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; 40 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/orders/{id}/fulfillment/set_hold_reason' \
-H 'Content-Type: application/json' \
-d '{
"reason_note": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment/set_hold_reason', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"reason_note": "string"
}),
});
const data = await response.json();import requests
payload = {
"reason_note": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/fulfillment/set_hold_reason', json=payload)
data = response.json(){
"reason_note": "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"
]
}Hold Fulfillments
Apply fulfillment holds on the preorder order's fulfillment orders.
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; 40 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/orders/{id}/hold_fulfillments'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/hold_fulfillments', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/hold_fulfillments')
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"
]
}Open Scheduled Fulfillments
Open the order's scheduled fulfillment orders for immediate fulfillment.
Note: Matches the merchant dashboard action Open scheduled fulfillments.
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; 40 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/orders/{id}/open_scheduled_fulfillments'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/open_scheduled_fulfillments', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/open_scheduled_fulfillments')
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"
]
}Payments
Read the deposit, remaining balance, and refund state of a preorder order.
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; 40 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/orders/{id}/payments'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Payments Charge Balance
Charge the remaining balance. auto uses the customer's saved payment method; manual just marks balance collected.
Note: auto may fail if no saved payment method or declined; check the response or poll status.
Body
modeanyParameters
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; 40 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/orders/{id}/payments/charge_balance' \
-H 'Content-Type: application/json' \
-d '{
"mode": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/charge_balance', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"mode": "string"
}),
});
const data = await response.json();import requests
payload = {
"mode": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/charge_balance', json=payload)
data = response.json(){
"mode": "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"
]
}Payments Refund
Refund the entire preorder (deposit + balance).
Body
notify_customeranynoteanyParameters
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; 40 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/orders/{id}/payments/refund' \
-H 'Content-Type: application/json' \
-d '{
"notify_customer": "string",
"note": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/refund', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"notify_customer": "string",
"note": "string"
}),
});
const data = await response.json();import requests
payload = {
"notify_customer": "string",
"note": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/refund', json=payload)
data = response.json(){
"notify_customer": "string",
"note": "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"
]
}Payments Refund Balance
Refund the remaining-balance portion of a preorder (only valid after the balance was collected).
Body
notify_customeranynoteanyParameters
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; 40 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/orders/{id}/payments/refund_balance' \
-H 'Content-Type: application/json' \
-d '{
"notify_customer": "string",
"note": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/refund_balance', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"notify_customer": "string",
"note": "string"
}),
});
const data = await response.json();import requests
payload = {
"notify_customer": "string",
"note": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/refund_balance', json=payload)
data = response.json(){
"notify_customer": "string",
"note": "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"
]
}Payments Refund Deposit
Refund the deposit portion of a preorder.
Body
notify_customeranynoteanyParameters
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; 40 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/orders/{id}/payments/refund_deposit' \
-H 'Content-Type: application/json' \
-d '{
"notify_customer": "string",
"note": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/refund_deposit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"notify_customer": "string",
"note": "string"
}),
});
const data = await response.json();import requests
payload = {
"notify_customer": "string",
"note": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/refund_deposit', json=payload)
data = response.json(){
"notify_customer": "string",
"note": "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"
]
}Payments Send Collection Url
Send the remaining-balance payment-collection URL to the customer.
Note: Idempotent — calling twice resends the email with a fresh URL.
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; 40 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/orders/{id}/payments/send_collection_url'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/send_collection_url', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/payments/send_collection_url')
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"
]
}Release
Release the order's fulfillment holds without applying offer-configured order tags.
Note: Matches the merchant dashboard action Release "On hold" fulfillments.
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.
Invalid lifecycle transition — read the message; don't retry blindly.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/orders/{id}/release'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/release', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/release')
data = response.json(){}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"Offer is already disabled"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Reschedule Fulfillment
Change the fulfillment date for the order's scheduled fulfillment orders.
Note: Accepts the same ISO 8601 timestamp as the merchant dashboard.
Body
fulfill_atstringrequiredParameters
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; 40 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/orders/{id}/reschedule_fulfillment' \
-H 'Content-Type: application/json' \
-d '{
"fulfill_at": "2026-07-01T00:00:00Z"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/reschedule_fulfillment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"fulfill_at": "2026-07-01T00:00:00Z"
}),
});
const data = await response.json();import requests
payload = {
"fulfill_at": "2026-07-01T00:00:00Z"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/reschedule_fulfillment', json=payload)
data = response.json(){
"fulfill_at": "2026-07-01T00:00:00Z"
}{}{
"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"
]
}Reschedule Payment
Change the due date for the order's remaining-balance payment schedule.
Note: Accepts a calendar date (YYYY-MM-DD) and changes the payment schedule only; it does not charge or refund money.
Body
due_atstringrequiredParameters
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; 40 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/orders/{id}/reschedule_payment' \
-H 'Content-Type: application/json' \
-d '{
"due_at": "2026-07-01T00:00:00Z"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/reschedule_payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"due_at": "2026-07-01T00:00:00Z"
}),
});
const data = await response.json();import requests
payload = {
"due_at": "2026-07-01T00:00:00Z"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/reschedule_payment', json=payload)
data = response.json(){
"due_at": "2026-07-01T00:00:00Z"
}{}{
"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"
]
}Split Fulfillment Orders
Split the order's fulfillment orders so preorder items ship separately from regular items.
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; 40 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/orders/{id}/split_fulfillment_orders'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/split_fulfillment_orders', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/split_fulfillment_orders')
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"
]
}Timeline
Order history / activity log for a preorder order: every notification sent, payment attempt, fulfillment hold, and order split, in order, with timestamps.
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; 40 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/orders/{id}/timeline'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/timeline', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/orders/{id}/timeline')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Bulk Cancel
Cancel many preorder orders (max 1000), with optional refund flags.
Body
order_idsanyrefund_depositanyrefund_balanceanynotify_customeranyreasonanyResponse
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; 40 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/orders/bulk_cancel' \
-H 'Content-Type: application/json' \
-d '{
"order_ids": [
"string"
],
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/bulk_cancel', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"order_ids": [
"string"
],
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}),
});
const data = await response.json();import requests
payload = {
"order_ids": [
"string"
],
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/bulk_cancel', json=payload)
data = response.json(){
"order_ids": [
"string"
],
"refund_deposit": "string",
"refund_balance": "string",
"notify_customer": "string",
"reason": "string"
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Bulk Release
Release fulfillments on many preorder orders (max 1000).
Body
order_idsanyResponse
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; 40 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/orders/bulk_release' \
-H 'Content-Type: application/json' \
-d '{
"order_ids": [
"string"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/bulk_release', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"order_ids": [
"string"
]
}),
});
const data = await response.json();import requests
payload = {
"order_ids": [
"string"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/bulk_release', json=payload)
data = response.json(){
"order_ids": [
"string"
]
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Bulk Send Payment Collection Url
Send payment-collection URLs to many preorder customers (max 1000).
Body
order_idsanyResponse
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; 40 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/orders/bulk_send_payment_collection_url' \
-H 'Content-Type: application/json' \
-d '{
"order_ids": [
"string"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/bulk_send_payment_collection_url', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"order_ids": [
"string"
]
}),
});
const data = await response.json();import requests
payload = {
"order_ids": [
"string"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/orders/bulk_send_payment_collection_url', json=payload)
data = response.json(){
"order_ids": [
"string"
]
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Jobs
Check the status of a bulk-order job.
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; 40 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/orders/jobs/{job_id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/orders/jobs/{job_id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/orders/jobs/{job_id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Preorders · Product Variants
List
List Shopify variants attached to any preorder offer in this shop.
Parameters
pageanyqueryper_pageanyqueryoffer_idanyqueryproduct_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; 40 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/product_variants'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/product_variants')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Read
Read a Shopify variant's preorder context: every offer it's in, aggregate counts, and current metafield state.
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; 40 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/product_variants/{variant_id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Detach From All Offers
Remove a variant from every preorder offer it's attached to. Customer orders are unaffected.
Note: Destructive. Same effect as calling Offer::Products::RemoveVariants against every offer the variant is in.
Parameters
variant_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; 40 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/product_variants/{variant_id}/detach_from_all_offers'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/detach_from_all_offers', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/detach_from_all_offers')
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"
]
}Offers
List the preorder offers a Shopify variant is attached to.
Parameters
variant_idstringrequiredpathstateanyqueryResponse
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; 40 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/product_variants/{variant_id}/offers'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/offers', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/offers')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Recalculate Preorder Count
Recompute preorder_count for a variant from active order line items, then push to Shopify.
Parameters
variant_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; 40 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/product_variants/{variant_id}/recalculate_preorder_count'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/recalculate_preorder_count', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/recalculate_preorder_count')
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"
]
}Reset Metafields
Clear a variant's preorder count metafields and rebuild its shipping text and limit metafields from its live offers. Keeps the variant attached to its offers.
Note: Doesn't detach. Shipping text and limit are cleared only where no live offer sets them.
Parameters
variant_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; 40 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/product_variants/{variant_id}/reset_metafields'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/reset_metafields', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/reset_metafields')
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"
]
}Reset Preorder Count
Hard-reset the preorder_count metafield + DB columns on a variant to zero.
Note: Use recalculate_preorder_count for a recompute from real orders; this is a destructive zero.
Parameters
variant_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; 40 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/product_variants/{variant_id}/reset_preorder_count'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/reset_preorder_count', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/reset_preorder_count')
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"
]
}Sync Metafields
Force-resync every preorder metafield for a variant from local DB state to Shopify.
Note: Idempotent. Useful when a previous metafield write failed.
Parameters
variant_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; 40 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/product_variants/{variant_id}/sync_metafields'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/sync_metafields', {
method: 'POST',
});
const data = await response.json();import requests
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/{variant_id}/sync_metafields')
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"
]
}Bulk Recalculate Preorder Counts
Recompute preorder_count for many variants in one job (max 5000).
Body
variant_idsanyResponse
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; 40 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/product_variants/bulk_recalculate_preorder_counts' \
-H 'Content-Type: application/json' \
-d '{
"variant_ids": [
"45000000001"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/bulk_recalculate_preorder_counts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"variant_ids": [
"45000000001"
]
}),
});
const data = await response.json();import requests
payload = {
"variant_ids": [
"45000000001"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/bulk_recalculate_preorder_counts', json=payload)
data = response.json(){
"variant_ids": [
"45000000001"
]
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Bulk Reset Metafields
Reset preorder metafields for many variants in one job (max 5000).
Body
variant_idsanyResponse
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; 40 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/product_variants/bulk_reset_metafields' \
-H 'Content-Type: application/json' \
-d '{
"variant_ids": [
"45000000001"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/bulk_reset_metafields', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"variant_ids": [
"45000000001"
]
}),
});
const data = await response.json();import requests
payload = {
"variant_ids": [
"45000000001"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/bulk_reset_metafields', json=payload)
data = response.json(){
"variant_ids": [
"45000000001"
]
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Bulk Sync Metafields
Force-resync preorder metafields for many variants in one job (max 5000).
Body
variant_idsanyResponse
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; 40 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/product_variants/bulk_sync_metafields' \
-H 'Content-Type: application/json' \
-d '{
"variant_ids": [
"45000000001"
]
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/bulk_sync_metafields', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"variant_ids": [
"45000000001"
]
}),
});
const data = await response.json();import requests
payload = {
"variant_ids": [
"45000000001"
]
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/product_variants/bulk_sync_metafields', json=payload)
data = response.json(){
"variant_ids": [
"45000000001"
]
}{}{
"job_id": "job_a1b2c3",
"status_url": "/api/v2/external/jobs/job_a1b2c3"
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Jobs
Check the status of a bulk variant-admin job.
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; 40 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/product_variants/jobs/{job_id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/product_variants/jobs/{job_id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/product_variants/jobs/{job_id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Preorders · Products
Inventory Status
Live Shopify inventory for a set of variants, plus a per-attached-offer diagnosis of whether the preorder button is eligible to show. Makes a live Shopify API call and may be slow.
Parameters
variant_idsanyrequiredqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/products/inventory_status'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/products/inventory_status', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/products/inventory_status')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Preorders · Reports
List
List every available preorder 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; 40 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/reports'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Balance Collection
Outstanding preorder balances and balance-collection performance metrics.
Parameters
fromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyquerycurrencyanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/balance_collection'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/balance_collection', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/balance_collection')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Balance Collection Export
Async CSV export of the balance-collection report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/balance_collection/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/balance_collection/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/balance_collection/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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"
]
}By Date
Time-series of all preorder metrics at the chosen granularity (day/week/month).
Parameters
fromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyqueryproduct_idanyqueryvariant_idanyquerymarket_idanyquerycurrencyanyquerygranularityanyquerymetricsanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/by_date'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_date', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/by_date')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}By Date Export
Async CSV export of the time-series preorder report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/by_date/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_date/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/by_date/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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"
]
}By Offer
Per-offer breakdown of preorder activity (orders, units, revenue, customers).
Parameters
fromanyquerytoanyqueryoffer_idsanyquerymarket_idanyquerycurrencyanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/by_offer'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_offer', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/by_offer')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}By Offer Export
Async CSV export of the per-offer preorder report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/by_offer/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_offer/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/by_offer/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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"
]
}By Product
Per-product preorder performance, rolled up across variants.
Parameters
fromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyqueryproduct_idanyquerycurrencyanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/by_product'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_product', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/by_product')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}By Product Export
Async CSV export of the per-product preorder report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/by_product/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_product/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/by_product/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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"
]
}By Variant
Per-variant preorder performance for a specific offer.
Note: Requires offer_id (or offer_ids[]). Variant-level data without an offer scope isn't supported.
Parameters
fromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyqueryproduct_idanyqueryvariant_idanyquerycurrencyanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/by_variant'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_variant', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/by_variant')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}By Variant Export
Async CSV export of the per-variant preorder report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/by_variant/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/by_variant/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/by_variant/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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"
]
}Cancellations
Preorder cancellation metrics with reason and per-offer breakdowns.
Note: Reason breakdown requires the cancel_reason field on OrderAttribution. Reasons not yet captured will appear as 'unknown'.
Parameters
fromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyquerycurrencyanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/cancellations'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/cancellations', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/cancellations')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Cancellations Export
Async CSV export of the cancellations report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/cancellations/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/cancellations/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/cancellations/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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"
]
}Customers
Paginated list of customers with preorder activity in the window.
Parameters
fromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyquerycurrencyanyquerypageanyqueryper_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; 40 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/reports/customers'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/customers', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/customers')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Customers Export
Async CSV export of the customers report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/customers/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/customers/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/customers/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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
Preorder button engagement/funnel analytics: impressions, add-to-carts, add-to-cart rate, orders, and order rate — the same numbers on the merchant's preorder Engagement dashboard. Rates use unique shoppers. order_rate can exceed 1.0 because orders come from placed preorder orders, a different denominator than unique add-to-carts.
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; 40 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/reports/engagement'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/engagement', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/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; 40 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/reports/exports/{job_id}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/exports/{job_id}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/exports/{job_id}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Revenue
Preorder revenue over a date window, bucketed by day/week/month.
Parameters
fromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyqueryproduct_idanyqueryvariant_idanyquerymarket_idanyquerycurrencyanyquerygranularityanyqueryinclude_depositsanyqueryinclude_balancesanyqueryResponse
Success — example response shown.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/revenue'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/revenue', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/revenue')
data = response.json(){
"window": {
"from": "2026-05-26T00:00:00Z",
"to": "2026-06-25T23:59:59Z"
},
"granularity": "day",
"currency": "USD",
"include_deposits": true,
"include_balances": true,
"total_revenue": "47825.50",
"series": [
{
"date": "2026-06-25T00:00:00Z",
"revenue": "2450.75",
"orders": 18
},
{
"date": "2026-06-24T00:00:00Z",
"revenue": "3180.25",
"orders": 24
}
],
"by_offer": [
{
"offer_id": 1,
"offer_name": "Summer Sneaker Drop",
"revenue": "28500.00"
},
{
"offer_id": 2,
"offer_name": "Winter Collection",
"revenue": "19325.50"
}
]
}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Revenue Export
Async CSV export of the preorder revenue report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/revenue/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/revenue/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/revenue/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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
High-level overview of preorder activity over a date window.
Parameters
rangestring | nullqueryfromanyquerytoanyqueryoffer_idanyqueryoffer_idsanyqueryproduct_idanyqueryvariant_idanyquerymarket_idanyquerycurrencyanyqueryResponse
Success — the requested resource.
Missing or invalid X-Auth-Token.
The request failed validation.
Rate limited — cost-weighted per token (read 1, write 2; 40 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/reports/summary'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/summary', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/reports/summary')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Summary Export
Async CSV export of the preorder summary report.
Body
fromanytoanyoffer_idanyoffer_idsanyproduct_idanyvariant_idanymarket_idanycurrencyanygranularityanymetricsanyinclude_depositsanyinclude_balancesanypageanyper_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; 40 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/reports/summary/export' \
-H 'Content-Type: application/json' \
-d '{
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/reports/summary/export', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}),
});
const data = await response.json();import requests
payload = {
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "string",
"page": "string",
"per_page": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/reports/summary/export', json=payload)
data = response.json(){
"from": "string",
"to": "string",
"offer_id": "string",
"offer_ids": [
"string"
],
"product_id": "78000000001",
"variant_id": "45000000001",
"market_id": "gid://shopify/Market/12345",
"currency": "string",
"granularity": "string",
"metrics": "string",
"include_deposits": "string",
"include_balances": "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"
]
}Preorders · Templates
Read
Read the position-0 preorder confirmation email/SMS template for a locale.
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; 40 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/templates/{locale}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/templates/{locale}', {
method: 'GET',
});
const data = await response.json();import requests
response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/templates/{locale}')
data = response.json(){}{
"errors": [
"Unauthorized"
]
}{
"errors": [
"Offer not found"
]
}{
"errors": [
"name is required"
]
}{
"errors": [
"Rate limit exceeded"
]
}Update
Update the position-0 preorder confirmation email/SMS template for a locale.
Note: Deep partial over the template fields. Rejects HTML (except in email_css_config) and runs Template validations and callbacks. email_reviews_title is the heading for the Judge.me reviews section that renders on the preorder confirmation email (for example "What customers are saying"). Colours are flat hex fields. Social links and the social icon colour are shared: saving one sets it on every notification template of the shop.
Body
email_subjectstringemail_preheaderstringemail_headerstringemail_descriptionstringemail_button_textstringemail_footerstringemail_reviews_titlestringpush_titlestringpush_bodystringpush_button_textstringsms_bodystringklaviyo_flow_namestringklaviyo_sms_flow_namestringemail_background_colorstringemail_section_colorstringemail_text_colorstringemail_border_radiusanyemail_button_background_colorstringemail_button_text_colorstringemail_button_border_radiusanyemail_css_configstringemail_facebook_linkstringemail_instagram_linkstringemail_pinterest_linkstringemail_twitter_linkstringemail_tiktok_linkstringemail_whatsapp_linkstringemail_youtube_linkstringemail_social_icon_colorstringemail_reviews_enabledbooleanemail_reviews_countanyemail_reviews_min_ratinganyParameters
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; 40 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/templates/{locale}' \
-H 'Content-Type: application/json' \
-d '{
"email_subject": "string",
"email_preheader": "string",
"email_header": "string",
"email_description": "string",
"email_button_text": "Preorder now",
"email_footer": "string",
"email_reviews_title": "string",
"push_title": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"sms_body": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_button_border_radius": "string",
"email_css_config": "string",
"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_reviews_enabled": true,
"email_reviews_count": 5,
"email_reviews_min_rating": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/templates/{locale}', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email_subject": "string",
"email_preheader": "string",
"email_header": "string",
"email_description": "string",
"email_button_text": "Preorder now",
"email_footer": "string",
"email_reviews_title": "string",
"push_title": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"sms_body": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_button_border_radius": "string",
"email_css_config": "string",
"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_reviews_enabled": true,
"email_reviews_count": 5,
"email_reviews_min_rating": "string"
}),
});
const data = await response.json();import requests
payload = {
"email_subject": "string",
"email_preheader": "string",
"email_header": "string",
"email_description": "string",
"email_button_text": "Preorder now",
"email_footer": "string",
"email_reviews_title": "string",
"push_title": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"sms_body": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_button_border_radius": "string",
"email_css_config": "string",
"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_reviews_enabled": True,
"email_reviews_count": 5,
"email_reviews_min_rating": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/templates/{locale}', json=payload)
data = response.json(){
"email_subject": "string",
"email_preheader": "string",
"email_header": "string",
"email_description": "string",
"email_button_text": "Preorder now",
"email_footer": "string",
"email_reviews_title": "string",
"push_title": "string",
"push_body": "string",
"push_button_text": "Preorder now",
"sms_body": "string",
"klaviyo_flow_name": "Summer Sneaker Drop",
"klaviyo_sms_flow_name": "Summer Sneaker Drop",
"email_background_color": "#1A1A1A",
"email_section_color": "#1A1A1A",
"email_text_color": "#1A1A1A",
"email_border_radius": "string",
"email_button_background_color": "#1A1A1A",
"email_button_text_color": "#1A1A1A",
"email_button_border_radius": "string",
"email_css_config": "string",
"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_reviews_enabled": true,
"email_reviews_count": 5,
"email_reviews_min_rating": "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"
]
}