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
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 · 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_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/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"
]
}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_idanyquerychannelanyquerysort_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_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/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_idanyquerychannelanyqueryResponse
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"
]
}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 — 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 — e.g. { channels: { sms: { enabled: true } } }.
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/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/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/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"
]
}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, scheduled_reports.daily, scheduled_reports.weekly, scheduled_reports.monthly — e.g. { scheduled_reports: { weekly: true } }. signups_threshold.count is the per-variant signup count that triggers the merchant alert email.
Body
signups_thresholdanyscheduled_reportsanyResponse
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",
"scheduled_reports": "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",
"scheduled_reports": "string"
}),
});
const data = await response.json();import requests
payload = {
"signups_threshold": "string",
"scheduled_reports": "string"
}
response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts', json=payload)
data = response.json(){
"signups_threshold": "string",
"scheduled_reports": "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).
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). locations.location_ids and any_variant.product_ids are arrays of Shopify numeric ids and are replaced wholesale when present.
Body
batchinganystock_thresholdanylocationsanyany_variantanyResponse
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"
}'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"
}),
});
const data = await response.json();import requests
payload = {
"batching": "string",
"stock_threshold": "string",
"locations": "string",
"any_variant": "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"
}{}{
"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"
]
}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.
Parameters
channelanyemailsmspushquerystatusanypendingnotifiedunsubscribedqueryvariant_idanyqueryproduct_idanyqueryemailanyqueryphoneanyqueryfromanyquerytoanyquerypageanyqueryper_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"
]
}Preorders · Offers
List
List preorder offers in this shop, paginated.
Parameters
pageanyqueryper_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/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_shipping_timeline": 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). custom_css is cleared by sending an empty string or null.
Body
line_item_propertiesanybutton_text_overridesanyuse_shopify_selling_plananycustom_cssanyParameters
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",
"custom_css": "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",
"custom_css": "string"
}),
});
const data = await response.json();import requests
payload = {
"line_item_properties": "string",
"button_text_overrides": "Preorder now",
"use_shopify_selling_plan": "string",
"custom_css": "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",
"custom_css": "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 Css
Set custom CSS overrides for this offer's storefront widget. Send an empty string to clear.
Body
cssanyParameters
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_css' \
-H 'Content-Type: application/json' \
-d '{
"css": "string"
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_custom_css', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"css": "string"
}),
});
const data = await response.json();import requests
payload = {
"css": "string"
}
response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_custom_css', json=payload)
data = response.json(){
"css": "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 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 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 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 whether the countdown timer follows the offer's schedule or a custom 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 unit labels for the countdown timer (Days/Hours/Mins/Secs).
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. Optionally flip attached variants' inventory policy to CONTINUE.
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}/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"
]
}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. 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
provideranyreservationanycontinue_sellinganyParameters
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 (at sale or at 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_customer.max: null removes the per-customer limit, total.max: null removes the total cap; display.show_remaining (true/false) toggles the remaining-units display on the storefront. Note: per_customer.max and total.max are stored config — storefront enforcement of these limits is follow-up work and not live yet.
Body
per_orderanyper_customeranytotalanydisplayanyParameters
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",
"per_customer": "string",
"total": "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",
"per_customer": "string",
"total": "string",
"display": "string"
}),
});
const data = await response.json();import requests
payload = {
"per_order": "string",
"per_customer": "string",
"total": "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",
"per_customer": "string",
"total": "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 Max Per Customer
Set the maximum quantity a single customer can preorder across all their orders.
Note: Stored config only today — storefront enforcement of the per-customer limit is follow-up work and not live yet. Clear the limit via PATCH .../limits with per_customer.max: null.
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_customer' \
-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_customer', {
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_customer', 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 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 Total Max
Set the total quantity that can be preordered across all customers.
Note: Stored config only today — storefront enforcement of the total cap is follow-up work and not live yet. Clear the cap via PATCH .../limits with total.max: null.
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_total_max' \
-H 'Content-Type: application/json' \
-d '{
"max": 5
}'const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/limits/set_total_max', {
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_total_max', 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"
]
}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 — 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 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.