Home

STOQ API v2 (Beta)

v2.0.0-beta

Contact: support@stoqapp.com

Base URL
https://app.stoqapp.com/api/v2/externalProduction

STOQ'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

ApiKeyAuthapiKey

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

API Key: X-Auth-Token in header

Account · Help Docs

Read

GET
https://app.stoqapp.com/api/v2/external/account/help_docs

Search the STOQ help centre, or read one help article in full. Use for how-to and explanation questions — how a feature works, how to set something up, what a setting means. Search first, then read the article that matches before relaying step-by-step instructions; the snippets are previews, not the whole answer.

Parameters

queryanyquery
urlanyquery
limitanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/help_docs'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/help_docs', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/help_docs')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Integrations

Read

GET
https://app.stoqapp.com/api/v2/external/account/integrations

Connection state of Klaviyo, Postscript, Omnisend and Mailchimp, where new signups are synced (Klaviyo, Omnisend, Mailchimp, Shopify customers, with the customer tag), the Mailchimp audience, and the Meta Pixel, Shopify Flow trigger and SplitOrder switches. Returns connected / verified flags only, never keys or tokens.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/integrations'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/integrations', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/integrations')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

PATCH
https://app.stoqapp.com/api/v2/external/account/integrations

Update the shop's integrations: sync signups to Klaviyo, Omnisend, Mailchimp or Shopify customers (with the customer tag), the Omnisend and Mailchimp API keys and Mailchimp audience, the Meta Pixel, Shopify Flow triggers and the SplitOrder app switch. API keys are write only; reads return connected flags.

Note: Deep partial. omnisend.api_key and mailchimp.api_key are never returned by any read; an empty string removes the saved key. A Mailchimp key is checked by fetching the account's audiences and is not saved when Mailchimp refuses it; mailchimp.list_id must be one of those audiences. Klaviyo connects with OAuth from the Integrations page; this action only turns its sync on or off. flow_triggers.triggers replaces the stored list.

Body

application/json
klaviyoany
omnisendany
mailchimpany
shopifyany
sync_customers_tagany
meta_pixelany
flow_triggersany
split_order_appany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/account/integrations' \
  -H 'Content-Type: application/json' \
  -d '{
    "klaviyo": "string",
    "omnisend": "string",
    "mailchimp": "string",
    "shopify": "string",
    "sync_customers_tag": "string",
    "meta_pixel": "string",
    "flow_triggers": "string",
    "split_order_app": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/integrations', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "klaviyo": "string",
      "omnisend": "string",
      "mailchimp": "string",
      "shopify": "string",
      "sync_customers_tag": "string",
      "meta_pixel": "string",
      "flow_triggers": "string",
      "split_order_app": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "klaviyo": "string",
  "omnisend": "string",
  "mailchimp": "string",
  "shopify": "string",
  "sync_customers_tag": "string",
  "meta_pixel": "string",
  "flow_triggers": "string",
  "split_order_app": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/account/integrations', json=payload)
data = response.json()
Request Body
{
  "klaviyo": "string",
  "omnisend": "string",
  "mailchimp": "string",
  "shopify": "string",
  "sync_customers_tag": "string",
  "meta_pixel": "string",
  "flow_triggers": "string",
  "split_order_app": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Languages

Read

GET
https://app.stoqapp.com/api/v2/external/account/languages

The shop's languages: default_locale (the language alerts and the signup widget use), app_locale (the dashboard language), whether multi-language support and translated product titles are on, and, when multi-language is on, the locales published in Shopify.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/languages'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/languages', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/languages')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

PATCH
https://app.stoqapp.com/api/v2/external/account/languages

Update the shop's language settings: the dashboard language (app_locale), multi-language alerts and widget, and translated product titles in alerts.

Note: app_locale only changes the merchant dashboard. multi_language_enabled false also turns product_translations_enabled off. product_translations_enabled true needs the read_translations access the Settings page asks for; the call fails until it is granted.

Body

application/json
app_localeany
multi_language_enabledany
product_translations_enabledany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/account/languages' \
  -H 'Content-Type: application/json' \
  -d '{
    "app_locale": "fr",
    "multi_language_enabled": true,
    "product_translations_enabled": true
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/languages', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "app_locale": "fr",
      "multi_language_enabled": true,
      "product_translations_enabled": true
    }),
});

const data = await response.json();
import requests

payload = {
  "app_locale": "fr",
  "multi_language_enabled": True,
  "product_translations_enabled": True
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/account/languages', json=payload)
data = response.json()
Request Body
{
  "app_locale": "fr",
  "multi_language_enabled": true,
  "product_translations_enabled": true
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Locations

Read

GET
https://app.stoqapp.com/api/v2/external/account/locations

The store's Shopify locations: id, name, and whether each is active. Use it to name the location ids in back-in-stock delivery settings and in markets.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/locations'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/locations', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/locations')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Markets

Read

GET
https://app.stoqapp.com/api/v2/external/account/markets

The store's Shopify Markets (international selling) configuration: active markets, whether the store sells to multiple markets, each market's countries, and which Shopify locations the merchant has linked to each market (location_ids). Distinct from an offer's market availability or restock-alert locations. Only active markets are returned by default.

Parameters

include_draftsanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/markets'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/markets', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/markets')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Plan Usage

Read

GET
https://app.stoqapp.com/api/v2/external/account/plan_usage

The shop's current STOQ plan and a billing month's usage vs included limits, with the usage-based charges STOQ has metered.

Parameters

periodanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/plan_usage'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/plan_usage', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/plan_usage')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Products

Read

GET
https://app.stoqapp.com/api/v2/external/account/products

List product variants with their preorder offer link (if any) and back-in-stock waitlist count, sorted by waitlist size (most demand first). search matches product name, variant title, SKU, a storefront/admin product URL, or a numeric/GID product or variant id. With match=product, search returns every variant of each matched product, not only the variants that matched.

Parameters

filteranyallpreorderback_in_stockquery
matchanyvariantproductquery
searchanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/products'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/products', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/products')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Sending

Read

GET
https://app.stoqapp.com/api/v2/external/account/sending

Who sends the shop's customer notifications: the email provider (stoq, klaviyo, flow) and SMS provider, the sender address, sender name and reply-to, the custom sending domain and its DKIM check, whether SMS sending is approved, and whose account sends: email_account and sms_account are "stoq" (STOQ's own email or SMS service, including sms_provider "twilio") or "merchant" (their Klaviyo, Postscript or Shopify Flow with saved credentials); email_sender_domain is "merchant" when mail comes from their verified address.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/sending'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/sending', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/sending')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

PATCH
https://app.stoqapp.com/api/v2/external/account/sending

Update who sends the shop's customer notifications: email and SMS provider, sender name, the merchant's own sending address, store domain in SMS links, Klaviyo marketing consent and the Postscript API key (write only). Also the email look every template shares: font, header and description text sizes, and logo size.

Note: Applies to back-in-stock and preorder notifications. use_custom_email_address true needs email_reply_to_address on a domain that is not a free mail provider, and DKIM set up for it before mail goes out from it. postscript_api_key is never returned by any read; it is checked with Postscript and not saved when Postscript refuses it; "" removes it.

Body

application/json
email_providerany
sms_providerany
email_from_nameany
use_custom_email_addressany
email_reply_to_addressany
sms_custom_domain_enabledany
klaviyo_skip_auto_subscribeany
postscript_api_keyany
email_styleany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/account/sending' \
  -H 'Content-Type: application/json' \
  -d '{
    "email_provider": "string",
    "sms_provider": "string",
    "email_from_name": "Summer Sneaker Drop",
    "use_custom_email_address": "string",
    "email_reply_to_address": "string",
    "sms_custom_domain_enabled": true,
    "klaviyo_skip_auto_subscribe": "string",
    "postscript_api_key": "string",
    "email_style": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/sending', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "email_provider": "string",
      "sms_provider": "string",
      "email_from_name": "Summer Sneaker Drop",
      "use_custom_email_address": "string",
      "email_reply_to_address": "string",
      "sms_custom_domain_enabled": true,
      "klaviyo_skip_auto_subscribe": "string",
      "postscript_api_key": "string",
      "email_style": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "email_provider": "string",
  "sms_provider": "string",
  "email_from_name": "Summer Sneaker Drop",
  "use_custom_email_address": "string",
  "email_reply_to_address": "string",
  "sms_custom_domain_enabled": True,
  "klaviyo_skip_auto_subscribe": "string",
  "postscript_api_key": "string",
  "email_style": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/account/sending', json=payload)
data = response.json()
Request Body
{
  "email_provider": "string",
  "sms_provider": "string",
  "email_from_name": "Summer Sneaker Drop",
  "use_custom_email_address": "string",
  "email_reply_to_address": "string",
  "sms_custom_domain_enabled": true,
  "klaviyo_skip_auto_subscribe": "string",
  "postscript_api_key": "string",
  "email_style": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Settings

Read

GET
https://app.stoqapp.com/api/v2/external/account/settings/{section_id}

One settings section: label, description, settings (the output of the read actions behind it, keyed by block, e.g. settings.widget is GET /back_in_stock/settings/widget), columns (field path => model column) and raw (field path => stored value). Sections: delivery_settings, signup_widget, notification_channels, notification_templates, preorder_notifications, preorder_pages, preorder_storefront_text, integrations, languages.

Parameters

section_idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/settings/{section_id}'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/settings/{section_id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/settings/{section_id}')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Setup

Read

GET
https://app.stoqapp.com/api/v2/external/account/setup

The shop's setup state: whether STOQ's app embed is on in the published theme (with the theme editor link that turns it on when it is off), and the getting-started steps for back in stock and preorders: each step's state, how many are done, the next one, and whether setup is complete.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/setup'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/setup', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/setup')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Templates

Translations

GET
https://app.stoqapp.com/api/v2/external/account/templates/{campaign_type}/translations

Read every translation override on a notification template, plus the full enumeration of translatable field paths, each field's default-locale source text, and every locale the shop has actually published.

Parameters

campaign_typestringrequiredpath
positionanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Translations
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/templates/{campaign_type}/translations'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/templates/{campaign_type}/translations', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/templates/{campaign_type}/translations')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Account · Translations

Read

GET
https://app.stoqapp.com/api/v2/external/account/translations

Read every translation override on the shop's notify-me button, signup form, and preorder button/modal text, plus the full enumeration of translatable field paths, each field's default-locale source text, and every locale the shop has actually published.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/account/translations'
const response = await fetch('https://app.stoqapp.com/api/v2/external/account/translations', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/account/translations')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Copilot

Settings

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings

Read all back-in-stock settings for a Copilot preview.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Settings
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Settings

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings

Patch back-in-stock channels, delivery, compliance, tagging, or alerts settings. delivery.batching.mode "multiplier" sends restocked-quantity x multiplier per batch; "fixed" sends batch_size per batch. delivery.stock_threshold must be >= 1. delivery.locations.location_ids and delivery.any_variant.product_ids REPLACE the stored list wholesale; any_variant.all_products true ignores product_ids. Enabling SMS for the first time puts sends on a verification hold until the shop is approved.

Body

application/json
channelsany
deliveryany
complianceany
taggingany
alertsany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Settings
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings' \
  -H 'Content-Type: application/json' \
  -d '{
    "channels": "string",
    "delivery": "string",
    "compliance": "string",
    "tagging": "string",
    "alerts": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "channels": "string",
      "delivery": "string",
      "compliance": "string",
      "tagging": "string",
      "alerts": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "channels": "string",
  "delivery": "string",
  "compliance": "string",
  "tagging": "string",
  "alerts": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/settings', json=payload)
data = response.json()
Request Body
{
  "channels": "string",
  "delivery": "string",
  "compliance": "string",
  "tagging": "string",
  "alerts": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Signups

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}

Read one back-in-stock signup for a Copilot preview.

Parameters

idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Signups
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Signups Create

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/create

Create one back-in-stock signup for the selected variant. channel must be "email" or "sms"; pass email for the email channel or phone for sms.

Body

application/json
channelanyrequired
quantityinteger
emailany
phoneany
nameany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Signups Create
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/create' \
  -H 'Content-Type: application/json' \
  -d '{
    "channel": "string",
    "quantity": 5,
    "email": "shopper@example.com",
    "phone": "+15551234567",
    "name": "Summer Sneaker Drop"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/create', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "channel": "string",
      "quantity": 5,
      "email": "shopper@example.com",
      "phone": "+15551234567",
      "name": "Summer Sneaker Drop"
    }),
});

const data = await response.json();
import requests

payload = {
  "channel": "string",
  "quantity": 5,
  "email": "shopper@example.com",
  "phone": "+15551234567",
  "name": "Summer Sneaker Drop"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/create', json=payload)
data = response.json()
Request Body
{
  "channel": "string",
  "quantity": 5,
  "email": "shopper@example.com",
  "phone": "+15551234567",
  "name": "Summer Sneaker Drop"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Signups Delete

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/delete

Delete one pending back-in-stock signup.

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Signups Delete
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/delete'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/delete', {
  method: 'POST',
});

const data = await response.json();
import requests

response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/delete')
data = response.json()
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Signups Notify

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/notify

Queue a notification for one back-in-stock signup.

Body

application/json
allow_resendany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Signups Notify
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/notify' \
  -H 'Content-Type: application/json' \
  -d '{
    "allow_resend": true
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/notify', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "allow_resend": true
    }),
});

const data = await response.json();
import requests

payload = {
  "allow_resend": True
}

response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/notify', json=payload)
data = response.json()
Request Body
{
  "allow_resend": true
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Signups Transfer

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/transfer

Transfer one pending back-in-stock signup to another variant. to_shopify_variant_id is the target Shopify variant ID (obtainable from get_offer_variants).

Body

application/json
to_shopify_variant_idanyrequired
to_shopify_product_idany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Signups Transfer
curl -X POST 'https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/transfer' \
  -H 'Content-Type: application/json' \
  -d '{
    "to_shopify_variant_id": "45000000001",
    "to_shopify_product_id": "78000000001"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/transfer', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "to_shopify_variant_id": "45000000001",
      "to_shopify_product_id": "78000000001"
    }),
});

const data = await response.json();
import requests

payload = {
  "to_shopify_variant_id": "45000000001",
  "to_shopify_product_id": "78000000001"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/back_in_stock/copilot/signups/{id}/transfer', json=payload)
data = response.json()
Request Body
{
  "to_shopify_variant_id": "45000000001",
  "to_shopify_product_id": "78000000001"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Notifications

List

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/notifications

List back-in-stock notifications (the send log) in this shop, paginated.

Note: status=blocked surfaces sends that did not go out, with blocked_reason (the stored text), blocked_reason_code and blocked_reason_label. Every response has a summary (total, sent, blocked, blocked_by_reason) that counts every row matching the filters, not only this page. group_by=product returns counts per product (sent, blocked, and blocked by reason code) instead of rows, paginated by product. A bare from/to date is that whole day in the shop's time zone.

Parameters

channelanyemailsmspushquery
statusanysentblockedquery
group_byanyproductquery
variant_idanyquery
product_idanyquery
fromanyquery
toanyquery
pageanyquery
per_pageanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

List
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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/notifications/{id}

Read one back-in-stock notification (a single send-log entry).

Parameters

idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/notifications/{id}'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/notifications/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/notifications/{id}')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Orders

List

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/orders

List orders placed after a back-in-stock alert, paginated. search matches order number/name, customer name, email, a Shopify order id (10+ digits), an order gid (gid://shopify/Order/), or a Shopify admin order URL.

Parameters

pageanyquery
per_pageanyquery
searchanyquery
customer_idanyquery
fromanyquery
toanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

List
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/orders'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/orders', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/orders')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Products

Read

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/products

Read per-product back-in-stock configuration: notify-me button visibility (always_show / when_out_of_stock / never_show), restock message and assigned template for each variant, plus whether the shop-level per-product customization toggle is on. Each row also has the variant's pending and total signups and its lifetime back-in-stock units sold and revenue. Filter with shopify_product_id, shopify_variant_id, overrides_only=true or has_waitlist=true. Rows are sorted by pending signups, most first.

Parameters

shopify_product_idanyquery
shopify_variant_idanyquery
overrides_onlyanyquery
has_waitlistanyquery
limitanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/products'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/products', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/products')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/products

Update per-product back-in-stock configuration for one or more products or variants (the "Back in stock alerts -> Products" tab). targets is a list; a target with shopify_variant_id changes just that VARIANT, a target with only shopify_product_id changes EVERY variant of that product. The same field values are applied to every target, so send one call per distinct set of values. button_visibility is one of "always_show" (notify-me button shown even while the item is IN stock -- WARNING: this also DISABLES automatic back-in-stock alerts for that variant, so the merchant has to notify signups manually), "when_out_of_stock" (the default: button appears only when out of stock and alerts send automatically) or "never_show" (button hidden on the storefront). restock_message is the free-text note shown under the button (e.g. "Back in stock March 15"); send an empty string to clear it. template is a back-in-stock template name or id, or "default" to fall back to the global widget design. automatic_alerts_enabled (true/false) directly sets whether this variant receives an automatic back-in-stock alert on restock -- the same control as the variant's own "Enable/Disable alerts" button, independent of button_visibility. Use this to fix a variant showing "Disabled" for automatic alerts in get_bis_products (get_bis_products.automatic_alerts_enabled), not button_visibility. If both button_visibility: "always_show" and automatic_alerts_enabled are sent in the same call, automatic_alerts_enabled wins. Per-product visibility/message/template values only take effect while the shop-level toggle configure_notify_me_enabled is on; when it is off this action refuses rather than store values that would not apply, unless enable_customization: true is passed, which turns the toggle on as part of this change (a no-op when already on). automatic_alerts_enabled is NOT gated by configure_notify_me_enabled -- it applies regardless. per_product_customization_enabled (true/false), sent on its own with no targets, turns that shop-level toggle on or off (off = the tab's "Disable per-product overrides").

Note: Bulk-safe: a single call may address up to 100 targets and writes them in one transaction with the Shopify metafield syncs fired once for the whole batch. A target STOQ has no product_variants row for is looked up in the shop's Shopify catalog; when it is there, its rows are created (one per variant for a product target) and the change is applied to them. Ids in neither are reported in unmatched. Deleting a back-in-stock template clears it from every product/variant it was assigned to (they fall back to the global design); template CRUD lives on the templates capability.

Body

application/json
targetsany
button_visibilityany
restock_messageany
templateany
enable_customizationany
automatic_alerts_enabledany
per_product_customization_enabledany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/products' \
  -H 'Content-Type: application/json' \
  -d '{
    "targets": "string",
    "button_visibility": "string",
    "restock_message": "string",
    "template": "string",
    "enable_customization": "string",
    "automatic_alerts_enabled": true,
    "per_product_customization_enabled": true
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/products', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "targets": "string",
      "button_visibility": "string",
      "restock_message": "string",
      "template": "string",
      "enable_customization": "string",
      "automatic_alerts_enabled": true,
      "per_product_customization_enabled": true
    }),
});

const data = await response.json();
import requests

payload = {
  "targets": "string",
  "button_visibility": "string",
  "restock_message": "string",
  "template": "string",
  "enable_customization": "string",
  "automatic_alerts_enabled": True,
  "per_product_customization_enabled": True
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/products', json=payload)
data = response.json()
Request Body
{
  "targets": "string",
  "button_visibility": "string",
  "restock_message": "string",
  "template": "string",
  "enable_customization": "string",
  "automatic_alerts_enabled": true,
  "per_product_customization_enabled": true
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Notification Status

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/products/{variant_id}/notification_status

Notification/waitlist status for one product variant: pending signups, total alerts sent, the 5 most recent send batches (each with what triggered it), and the shop's delivery settings -- the usual reason a restock produced no send yet.

Parameters

variant_idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Notification Status
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/products/{variant_id}/notification_status'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/products/{variant_id}/notification_status', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/products/{variant_id}/notification_status')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Reports

List

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports

List every available back-in-stock report (name, description, aliases, url).

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

List
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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions

Time-series of orders attributed to back-in-stock alerts, the revenue recovered, and the distinct customers who placed them.

Note: Unscoped requests read the daily rollups plus today, as the Overview chart does; there unique_customers is summed per day, so a customer who bought on two days counts twice. range=all_time starts at the install date.

Parameters

fromanyquery
toanyquery
rangeanyquery
variant_idanyquery
product_idanyquery
channelanyquery
market_idanyquery
granularityanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Conversions
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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/conversions/export

Async CSV export of the back-in-stock conversions time series.

Body

application/json
fromany
toany
variant_idany
product_idany
channelany
granularityany
sort_byany
directionany
pageany
per_pageany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Conversions Export
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()
Request Body
{
  "from": "string",
  "to": "string",
  "variant_id": "45000000001",
  "product_id": "78000000001",
  "channel": "string",
  "granularity": "string",
  "sort_by": "string",
  "direction": "string",
  "page": "string",
  "per_page": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Engagement

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/engagement

Back-in-stock "Notify me" button engagement/funnel analytics: impressions, clicks, click rate, signups, and signup rate — the same numbers on the merchant's back-in-stock Engagement dashboard. Rates use unique shoppers. This is button engagement, not conversion — for orders placed by notified customers use /back_in_stock/reports/summary.

Parameters

fromanyquery
toanyquery
market_idanyquery
variant_idsanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Engagement
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/engagement'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/engagement', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/engagement')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Exports

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/exports/{job_id}

Check the status of an async report export and get the download URL when ready.

Parameters

job_idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Exports
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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications

Time-series of back-in-stock notifications sent, split by channel (email/sms/push), with blocked sends and the emails and delivered SMS messages behind them.

Note: sent counts notifications by when they were sent; blocked by when they were attempted. emails_sent and sms_delivered count the messages behind them; unscoped requests read those two from the daily rollups, as the Overview chart does. range=all_time starts at the install date.

Parameters

fromanyquery
toanyquery
rangeanyquery
variant_idanyquery
product_idanyquery
channelanyquery
market_idanyquery
granularityanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Notifications
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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/notifications/export

Async CSV export of the back-in-stock notifications time series.

Body

application/json
fromany
toany
variant_idany
product_idany
channelany
granularityany
sort_byany
directionany
pageany
per_pageany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Notifications Export
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand

Ranked variants (or products) by back-in-stock demand: signups waiting now, signups created in the window, last requested.

Note: pending counts the waitlist now and ignores the window; total counts signups created in the window. group_by=product ranks products instead of variants.

Parameters

group_byanyvariantproductquery
fromanyquery
toanyquery
rangeanyquery
variant_idanyquery
product_idanyquery
channelanyquery
market_idanyquery
sort_byanyquery
directionanyquery
pageanyquery
per_pageanyquery

Response

200OKobject

Success — example response shown.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Products In Demand
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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/products_in_demand/export

Async CSV export of the back-in-stock products-in-demand report.

Body

application/json
fromany
toany
variant_idany
product_idany
channelany
granularityany
sort_byany
directionany
pageany
per_pageany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Products In Demand Export
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups

Time-series of back-in-stock signups created (day/week/month), with how many of them are still waiting and how many signups were notified in each bucket.

Note: signups counts signups created in the bucket; pending is how many of those are waiting now; notified counts signups notified in the bucket. Unscoped requests read signups from the daily rollups, as the Overview chart does. range=all_time starts at the shop's install date.

Parameters

fromanyquery
toanyquery
rangeanyquery
variant_idanyquery
product_idanyquery
channelanyquery
market_idanyquery
granularityanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Signups
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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups/export

Async CSV export of the back-in-stock signups time series.

Body

application/json
fromany
toany
variant_idany
product_idany
channelany
granularityany
sort_byany
directionany
pageany
per_pageany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Signups Export
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary

Back-in-stock totals over a window: signups created, signups waiting now, signups and distinct customers notified in the window, attributed orders, conversion rate and recovered revenue. range=all_time covers the shop's whole history.

Note: Unscoped requests match the Back in Stock Overview: all-time signups, orders and revenue come from the shop's lifetime counters, a window's from the daily rollups plus today (source says which). pending and pending_by_channel are the waitlist now and ignore the window. last_notified_at is the latest send for the scope, whatever the window.

Parameters

fromanyquery
toanyquery
rangeanyquery
variant_idanyquery
product_idanyquery
channelanyquery
market_idanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Summary
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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/summary/export

Async CSV export of the back-in-stock summary report.

Body

application/json
fromany
toany
variant_idany
product_idany
channelany
granularityany
sort_byany
directionany
pageany
per_pageany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Summary Export
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()
Request Body
{
  "from": "string",
  "to": "string",
  "variant_id": "45000000001",
  "product_id": "78000000001",
  "channel": "string",
  "granularity": "string",
  "sort_by": "string",
  "direction": "string",
  "page": "string",
  "per_page": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Wait Duration

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/reports/wait_duration

How long back-in-stock shoppers have been waiting: median wait days, the longest wait, and a binned wait-time histogram (paid plans only). Also returns total_waiting, the current pending/opted-in signup count.

Parameters

variant_idanyquery
product_idanyquery
market_idanyquery
fromanyquery
toanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Wait Duration
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/wait_duration'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/wait_duration', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/reports/wait_duration')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Settings

Read

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/settings

Read all back-in-stock settings for the shop.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
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

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/settings

Update back-in-stock settings for the shop.

Note: Accepts any combination of capability blobs: channels, delivery, compliance, tagging, alerts, widget — deep partial, delegated to the capability PATCHes, errors accumulated. Boolean toggles are set via this PATCH (or the capability PATCH): channels.email.enabled, channels.sms.enabled, channels.push.enabled, delivery.batching.enabled, delivery.locations.filter_enabled, delivery.any_variant.enabled, compliance.optin_required, tagging.order_tags.enabled, alerts.signups_threshold.notify, alerts.scheduled_reports.daily, alerts.scheduled_reports.weekly, alerts.scheduled_reports.monthly, widget.placement.enabled — e.g. { channels: { sms: { enabled: true } } }.

Body

application/json
channelsany
deliveryany
complianceany
taggingany
alertsany
widgetany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings' \
  -H 'Content-Type: application/json' \
  -d '{
    "channels": "string",
    "delivery": "string",
    "compliance": "string",
    "tagging": "string",
    "alerts": "string",
    "widget": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "channels": "string",
      "delivery": "string",
      "compliance": "string",
      "tagging": "string",
      "alerts": "string",
      "widget": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "channels": "string",
  "delivery": "string",
  "compliance": "string",
  "tagging": "string",
  "alerts": "string",
  "widget": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings', json=payload)
data = response.json()
Request Body
{
  "channels": "string",
  "delivery": "string",
  "compliance": "string",
  "tagging": "string",
  "alerts": "string",
  "widget": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Alerts

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts

Read back-in-stock merchant alert and scheduled report settings.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Alerts
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

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts

Update back-in-stock merchant alert and scheduled report settings.

Note: Toggles set via this PATCH: signups_threshold.notify, signup_alerts.enabled, scheduled_reports.daily, scheduled_reports.weekly, scheduled_reports.monthly, notify_on_alert_sent — e.g. { scheduled_reports: { weekly: true } }. signups_threshold.count is the per-variant signup count that triggers the high-demand merchant alert email. signup_alerts.enabled turns on an immediate email to the merchant for every individual signup, sent to signup_alerts.email. scheduled_reports.email is the address that receives the daily/weekly/monthly summary reports. notify_on_alert_sent emails the merchant whenever back-in-stock alerts are sent to customers. merchant_emails.product_updates and merchant_emails.theme_published turn STOQ's own emails to the merchant on or off.

Body

application/json
signups_thresholdany
signup_alertsany
scheduled_reportsany
notify_on_alert_sentany
merchant_emailsany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Alerts
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts' \
  -H 'Content-Type: application/json' \
  -d '{
    "signups_threshold": "string",
    "signup_alerts": "string",
    "scheduled_reports": "string",
    "notify_on_alert_sent": "string",
    "merchant_emails": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "signups_threshold": "string",
      "signup_alerts": "string",
      "scheduled_reports": "string",
      "notify_on_alert_sent": "string",
      "merchant_emails": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "signups_threshold": "string",
  "signup_alerts": "string",
  "scheduled_reports": "string",
  "notify_on_alert_sent": "string",
  "merchant_emails": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/alerts', json=payload)
data = response.json()
Request Body
{
  "signups_threshold": "string",
  "signup_alerts": "string",
  "scheduled_reports": "string",
  "notify_on_alert_sent": "string",
  "merchant_emails": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Channels

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels

Read back-in-stock notification channel settings.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Channels
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

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/channels

Update back-in-stock notification channel toggles, and the master switch for automatic back-in-stock alerts.

Note: Channel toggles are set via this PATCH: email.enabled, sms.enabled, push.enabled — e.g. { sms: { enabled: true } }. alerts_enabled false stops automatic back-in-stock alerts on every channel, whatever the channel switches say. Enabling SMS for the first time triggers a restricted-content verification check; sends may be held until the shop is verified.

Body

application/json
alerts_enabledany
emailany
smsany
pushany

Response

200OKobject

Success — example response shown.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Channels
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/compliance

Read back-in-stock compliance settings (double opt-in).

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Compliance
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

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/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

application/json
optin_requiredany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Compliance
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery

Read back-in-stock delivery settings (batching, stock threshold, locations, any-variant).

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Delivery
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

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery

Update back-in-stock delivery settings (batching, stock threshold, locations, any-variant, password-protected sending, market setup, market-based alerts, alerts on publish).

Note: Deep partial. Toggles set via this PATCH: batching.enabled, locations.filter_enabled, any_variant.enabled — e.g. { batching: { enabled: true } }. batching.mode is an enum: 'multiplier' (batch size = restocked quantity x batching.multiplier) or 'fixed' (batch size = batching.batch_size); batching.wait_hours is the wait between batches. stock_threshold is the minimum restocked quantity before notifications send (>= 1). any_variant.all_products is a boolean: when true, any-variant alerts apply to every product and any_variant.product_ids is ignored; when false, only the listed products qualify. locations.location_ids and any_variant.product_ids are arrays of Shopify numeric ids and are replaced wholesale when present. send_while_password_protected is a boolean: false (default) holds back-in-stock alerts while the storefront password is on (signups stay pending for the next restock); true sends anyway. market_setup is "single_market" or "multiple_markets"; market_locations_enabled turns on market-based alerts; alert_on_publish also alerts when a product is published.

Body

application/json
batchingany
stock_thresholdany
locationsany
any_variantany
send_while_password_protectedany
market_setupany
market_locations_enabledany
alert_on_publishany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Delivery
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery' \
  -H 'Content-Type: application/json' \
  -d '{
    "batching": "string",
    "stock_threshold": "string",
    "locations": "string",
    "any_variant": "string",
    "send_while_password_protected": "string",
    "market_setup": "gid://shopify/Market/12345",
    "market_locations_enabled": "gid://shopify/Market/12345",
    "alert_on_publish": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "batching": "string",
      "stock_threshold": "string",
      "locations": "string",
      "any_variant": "string",
      "send_while_password_protected": "string",
      "market_setup": "gid://shopify/Market/12345",
      "market_locations_enabled": "gid://shopify/Market/12345",
      "alert_on_publish": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "batching": "string",
  "stock_threshold": "string",
  "locations": "string",
  "any_variant": "string",
  "send_while_password_protected": "string",
  "market_setup": "gid://shopify/Market/12345",
  "market_locations_enabled": "gid://shopify/Market/12345",
  "alert_on_publish": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery', json=payload)
data = response.json()
Request Body
{
  "batching": "string",
  "stock_threshold": "string",
  "locations": "string",
  "any_variant": "string",
  "send_while_password_protected": "string",
  "market_setup": "gid://shopify/Market/12345",
  "market_locations_enabled": "gid://shopify/Market/12345",
  "alert_on_publish": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Tagging

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/tagging

Read back-in-stock order tagging settings.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Tagging
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

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/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

application/json
order_tagsany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Tagging
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()
Request Body
{
  "order_tags": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Widget

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget

Read the storefront back-in-stock signup widget configuration: the notify-me button, where it appears, and the signup form's copy, styling and inputs.

Parameters

localeanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Widget
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Widget

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget

Update the storefront back-in-stock signup widget: the notify-me button (text, colors, corner radius, font, position), where the button appears (product, collection, home, search, preorder pages, and whether the whole widget is enabled), and the signup form's copy, success/error messages, colors, which inputs are collected and the double opt-in email text. button.position is "auto" (in-flow, directly below the sold-out add-to-cart button), "float-right" or "float-left" (a floating tab pinned to that edge of the page) or "specific" (after the element placement.selectors.product finds). placement.selectors holds the CSS selectors that place the button on product, collection, home and search pages; placement.hide_by_tag limits the widget by product tag; form.inline shows the form on the page instead of a popup; custom.css and custom.javascript run on every storefront page. form.fields.sms_first is a boolean: true shows the SMS field before email. form.fields.sms_default_country is a lowercase ISO 3166-1 alpha-2 code (e.g. "us", "gb", "ca", "au"). form.fields.sms_allowed_countries takes { add: [...], remove: [...] } of those same codes and edits the stored list in place — it never replaces it, so one country can be added or dropped without resending the rest; an empty allowed list means every country is allowed. Colors must be hex (#RRGGBB); radii are integers in pixels. Pass an optional top-level locale (e.g. "fr") to write the text fields for that language only.

Note: Deep partial. Groups: button, placement (with selectors and hide_by_tag), form.copy, form.messages, form.style, form.fields, form.inline, optin, branding, custom. Selectors, the on-page form, custom CSS/JavaScript and the app proxy path change what every shopper sees; a wrong value can hide the widget. Channel enables (email/sms/push), optin_required and the merchant signup alert live on the other settings capabilities.

Body

application/json
localeany
buttonany
placementany
formany
optinany
brandingany
customany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Widget
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget' \
  -H 'Content-Type: application/json' \
  -d '{
    "locale": "fr",
    "button": "string",
    "placement": "string",
    "form": "string",
    "optin": "string",
    "branding": "string",
    "custom": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "locale": "fr",
      "button": "string",
      "placement": "string",
      "form": "string",
      "optin": "string",
      "branding": "string",
      "custom": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "locale": "fr",
  "button": "string",
  "placement": "string",
  "form": "string",
  "optin": "string",
  "branding": "string",
  "custom": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/widget', json=payload)
data = response.json()
Request Body
{
  "locale": "fr",
  "button": "string",
  "placement": "string",
  "form": "string",
  "optin": "string",
  "branding": "string",
  "custom": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Signups

List

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/signups

List back-in-stock signups (the waitlist) in this shop, paginated.

Note: status compiles notified_at / unsubscribed_at / blocked_at into one lifecycle value; email and phone filters match partial values on the signup or its customer; query matches the customer's name, email or phone with one term (use email/phone instead to match only one). summary counts every signup matching the filters by status (total, pending, notified, blocked, unsubscribed), not only this page. A bare from/to date is that whole day in the shop's time zone.

Parameters

channelanyemailsmspushquery
statusanypendingnotifiedblockedunsubscribedquery
variant_idanyquery
product_idanyquery
queryanyquery
emailanyquery
phoneanyquery
fromanyquery
toanyquery
pageanyquery
per_pageanyquery

Response

200OKobject

Success — example response shown.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

List
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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/signups

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

application/json
channelanyemailsmsrequired
shopify_variant_idanyrequired
quantityinteger
shopify_product_idany
emailany
phoneany
nameany

Response

200OKobject

Success — example response shown.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Create
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}

Read one back-in-stock signup's full representation.

Parameters

idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
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
https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}

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

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Delete
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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/signups/{id}/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

application/json
allow_resendany

Parameters

idstringrequiredpath

Response

200OKobject

Success — example response shown.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Notify
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()
Request Body
{
  "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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/signups/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

application/json
signup_idsArray<string>required

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Bulk Delete
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()
Request Body
{
  "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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/signups/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

application/json
signup_idsArray<string>required
allow_resendany

Response

200OKobject

Success — example response shown.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Bulk Notify
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()
Request Body
{
  "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

POST
https://app.stoqapp.com/api/v2/external/back_in_stock/signups/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

application/json
from_shopify_variant_idanyrequired
to_shopify_variant_idanyrequired
to_shopify_product_idanyrequired
scopeanypendingnotifiedall
from_shopify_product_idany

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Transfer
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()
Request Body
{
  "from_shopify_variant_id": "45000000001",
  "to_shopify_variant_id": "45000000001",
  "to_shopify_product_id": "78000000001",
  "scope": "pending",
  "from_shopify_product_id": "78000000001"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Back In Stock · Templates

Read

GET
https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}

Read a localized back-in-stock notification template. stage is "initial" (the back-in-stock alert), "reminder" (the follow-up reminder) or "signup_thank_you" (the email/SMS sent right after a customer signs up). The numbers 0 and 1 are accepted as aliases for initial and reminder. Includes enabled, the stage's on/off switch.

Parameters

stagestringrequiredpath
localestringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

PATCH
https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}

Update a localized back-in-stock notification template. stage is "initial" (the back-in-stock alert), "reminder" (the follow-up reminder) or "signup_thank_you" (the email/SMS sent right after a customer signs up); 0 and 1 are aliases for initial and reminder. enabled (true/false) turns the reminder or the signup thank-you on or off; the initial alert cannot be disabled here. email_button_destination and sms_link_destination each accept only "checkout" or "product". Social links (email_facebook_link, email_instagram_link, email_pinterest_link, email_twitter_link, email_tiktok_link, email_whatsapp_link, email_youtube_link) take the profile URL without https:// and show as icons in the email; they are the ONLY place for social links — never put links in the footer. Colours (email_background_color, email_text_color, email_button_background_color, email_button_text_color) are flat hex fields — there is no nested style object. email_template_enabled (true/false) is the "Use HTML template" switch: false goes back to the standard STOQ email, true uses the custom HTML email template (email_template). Colours, corner radii and the Judge.me reviews block are shared by every stage of the alert; social links, the social icon colour and email_unsubscribe_text by every template of the shop.

Note: Deep partial over the template fields plus the stage's enabled switch. Rejects HTML except in email_template and email_css_config, and runs Template validations and callbacks. email_button_destination and sms_link_destination each accept only "checkout" or "product" (product page).

Body

application/json
enabledboolean
email_template_enabledboolean
email_reviews_enabledboolean
email_button_textstring
email_button_destinationstring
email_descriptionstring
email_footerstring
email_preheaderstring
email_headerstring
email_subjectstring
push_bodystring
push_button_textstring
push_titlestring
sms_bodystring
sms_link_destinationstring
klaviyo_flow_namestring
klaviyo_sms_flow_namestring
email_background_colorstring
email_text_colorstring
email_button_background_colorstring
email_button_text_colorstring
email_facebook_linkstring
email_instagram_linkstring
email_pinterest_linkstring
email_twitter_linkstring
email_tiktok_linkstring
email_whatsapp_linkstring
email_youtube_linkstring
email_social_icon_colorstring
email_section_colorstring
email_border_radiusany
email_button_border_radiusany
email_unsubscribe_textstring
email_reviews_titlestring
email_reviews_countany
email_reviews_min_ratingany
email_css_configstring
email_templatestring

Parameters

stagestringrequiredpath
localestringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled": true,
    "email_template_enabled": true,
    "email_reviews_enabled": true,
    "email_button_text": "Preorder now",
    "email_button_destination": "string",
    "email_description": "string",
    "email_footer": "string",
    "email_preheader": "string",
    "email_header": "string",
    "email_subject": "string",
    "push_body": "string",
    "push_button_text": "Preorder now",
    "push_title": "string",
    "sms_body": "string",
    "sms_link_destination": "string",
    "klaviyo_flow_name": "Summer Sneaker Drop",
    "klaviyo_sms_flow_name": "Summer Sneaker Drop",
    "email_background_color": "#1A1A1A",
    "email_text_color": "#1A1A1A",
    "email_button_background_color": "#1A1A1A",
    "email_button_text_color": "#1A1A1A",
    "email_facebook_link": "string",
    "email_instagram_link": "string",
    "email_pinterest_link": "string",
    "email_twitter_link": "string",
    "email_tiktok_link": "string",
    "email_whatsapp_link": "string",
    "email_youtube_link": "string",
    "email_social_icon_color": "#1A1A1A",
    "email_section_color": "#1A1A1A",
    "email_border_radius": "string",
    "email_button_border_radius": "string",
    "email_unsubscribe_text": "Preorder now",
    "email_reviews_title": "string",
    "email_reviews_count": 5,
    "email_reviews_min_rating": "string",
    "email_css_config": "string",
    "email_template": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "enabled": true,
      "email_template_enabled": true,
      "email_reviews_enabled": true,
      "email_button_text": "Preorder now",
      "email_button_destination": "string",
      "email_description": "string",
      "email_footer": "string",
      "email_preheader": "string",
      "email_header": "string",
      "email_subject": "string",
      "push_body": "string",
      "push_button_text": "Preorder now",
      "push_title": "string",
      "sms_body": "string",
      "sms_link_destination": "string",
      "klaviyo_flow_name": "Summer Sneaker Drop",
      "klaviyo_sms_flow_name": "Summer Sneaker Drop",
      "email_background_color": "#1A1A1A",
      "email_text_color": "#1A1A1A",
      "email_button_background_color": "#1A1A1A",
      "email_button_text_color": "#1A1A1A",
      "email_facebook_link": "string",
      "email_instagram_link": "string",
      "email_pinterest_link": "string",
      "email_twitter_link": "string",
      "email_tiktok_link": "string",
      "email_whatsapp_link": "string",
      "email_youtube_link": "string",
      "email_social_icon_color": "#1A1A1A",
      "email_section_color": "#1A1A1A",
      "email_border_radius": "string",
      "email_button_border_radius": "string",
      "email_unsubscribe_text": "Preorder now",
      "email_reviews_title": "string",
      "email_reviews_count": 5,
      "email_reviews_min_rating": "string",
      "email_css_config": "string",
      "email_template": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "enabled": True,
  "email_template_enabled": True,
  "email_reviews_enabled": True,
  "email_button_text": "Preorder now",
  "email_button_destination": "string",
  "email_description": "string",
  "email_footer": "string",
  "email_preheader": "string",
  "email_header": "string",
  "email_subject": "string",
  "push_body": "string",
  "push_button_text": "Preorder now",
  "push_title": "string",
  "sms_body": "string",
  "sms_link_destination": "string",
  "klaviyo_flow_name": "Summer Sneaker Drop",
  "klaviyo_sms_flow_name": "Summer Sneaker Drop",
  "email_background_color": "#1A1A1A",
  "email_text_color": "#1A1A1A",
  "email_button_background_color": "#1A1A1A",
  "email_button_text_color": "#1A1A1A",
  "email_facebook_link": "string",
  "email_instagram_link": "string",
  "email_pinterest_link": "string",
  "email_twitter_link": "string",
  "email_tiktok_link": "string",
  "email_whatsapp_link": "string",
  "email_youtube_link": "string",
  "email_social_icon_color": "#1A1A1A",
  "email_section_color": "#1A1A1A",
  "email_border_radius": "string",
  "email_button_border_radius": "string",
  "email_unsubscribe_text": "Preorder now",
  "email_reviews_title": "string",
  "email_reviews_count": 5,
  "email_reviews_min_rating": "string",
  "email_css_config": "string",
  "email_template": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{stage}/{locale}', json=payload)
data = response.json()
Request Body
{
  "enabled": true,
  "email_template_enabled": true,
  "email_reviews_enabled": true,
  "email_button_text": "Preorder now",
  "email_button_destination": "string",
  "email_description": "string",
  "email_footer": "string",
  "email_preheader": "string",
  "email_header": "string",
  "email_subject": "string",
  "push_body": "string",
  "push_button_text": "Preorder now",
  "push_title": "string",
  "sms_body": "string",
  "sms_link_destination": "string",
  "klaviyo_flow_name": "Summer Sneaker Drop",
  "klaviyo_sms_flow_name": "Summer Sneaker Drop",
  "email_background_color": "#1A1A1A",
  "email_text_color": "#1A1A1A",
  "email_button_background_color": "#1A1A1A",
  "email_button_text_color": "#1A1A1A",
  "email_facebook_link": "string",
  "email_instagram_link": "string",
  "email_pinterest_link": "string",
  "email_twitter_link": "string",
  "email_tiktok_link": "string",
  "email_whatsapp_link": "string",
  "email_youtube_link": "string",
  "email_social_icon_color": "#1A1A1A",
  "email_section_color": "#1A1A1A",
  "email_border_radius": "string",
  "email_button_border_radius": "string",
  "email_unsubscribe_text": "Preorder now",
  "email_reviews_title": "string",
  "email_reviews_count": 5,
  "email_reviews_min_rating": "string",
  "email_css_config": "string",
  "email_template": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Preorders · Developer Settings

Read

GET
https://app.stoqapp.com/api/v2/external/preorders/developer_settings

The preorder Developer settings: whether dev mode is on, and the custom CSS selectors that place the Preorder button and each preorder element on product pages. Shop-wide, not per offer. The selectors are used only while dev_mode_enabled is true.

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/developer_settings'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/developer_settings', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/developer_settings')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Preorders · Notifications

Read

GET
https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}

Read shop-level preorder notification settings for a locale. email_account and sms_account say whose account sends: "stoq" or "merchant" (see GET /account/sending).

Parameters

localestringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

PATCH
https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}

Update shop-level preorder notification settings for a locale. This edits shop-level toggles, provider (email_provider/sms_provider), sender name, and shipping-update / payment-collection copy — NOT the confirmation email body (use update_preorder_template for that). email_provider and sms_provider accept only the shop's enabled provider keys.

Note: Deep partial. Validates booleans, provider enums, locale, length, and plain-text content; then runs Setting validations and provider/SMS verification callbacks.

Body

application/json
preorder_email_enabledboolean
preorder_sms_enabledboolean
preorder_cancellation_enabledboolean
notify_payment_collection_enabledboolean
email_provideranystoqklaviyoflow
sms_provideranytwiliotelnyxinfobipklaviyopostscript
email_from_namestring
shipping_update_subjectstring
shipping_update_headerstring
shipping_update_descriptionstring
payment_collection_email_subjectstring
payment_collection_email_headerstring
payment_collection_email_descriptionstring
payment_collection_email_button_textstring
klaviyo_shipping_update_flow_namestring
klaviyo_payment_failed_flow_namestring

Parameters

localestringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}' \
  -H 'Content-Type: application/json' \
  -d '{
    "preorder_email_enabled": true,
    "preorder_sms_enabled": true,
    "preorder_cancellation_enabled": true,
    "notify_payment_collection_enabled": true,
    "email_provider": "stoq",
    "sms_provider": "twilio",
    "email_from_name": "Summer Sneaker Drop",
    "shipping_update_subject": "2026-07-01T00:00:00Z",
    "shipping_update_header": "2026-07-01T00:00:00Z",
    "shipping_update_description": "2026-07-01T00:00:00Z",
    "payment_collection_email_subject": "string",
    "payment_collection_email_header": "string",
    "payment_collection_email_description": "string",
    "payment_collection_email_button_text": "Preorder now",
    "klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
    "klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "preorder_email_enabled": true,
      "preorder_sms_enabled": true,
      "preorder_cancellation_enabled": true,
      "notify_payment_collection_enabled": true,
      "email_provider": "stoq",
      "sms_provider": "twilio",
      "email_from_name": "Summer Sneaker Drop",
      "shipping_update_subject": "2026-07-01T00:00:00Z",
      "shipping_update_header": "2026-07-01T00:00:00Z",
      "shipping_update_description": "2026-07-01T00:00:00Z",
      "payment_collection_email_subject": "string",
      "payment_collection_email_header": "string",
      "payment_collection_email_description": "string",
      "payment_collection_email_button_text": "Preorder now",
      "klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
      "klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
    }),
});

const data = await response.json();
import requests

payload = {
  "preorder_email_enabled": True,
  "preorder_sms_enabled": True,
  "preorder_cancellation_enabled": True,
  "notify_payment_collection_enabled": True,
  "email_provider": "stoq",
  "sms_provider": "twilio",
  "email_from_name": "Summer Sneaker Drop",
  "shipping_update_subject": "2026-07-01T00:00:00Z",
  "shipping_update_header": "2026-07-01T00:00:00Z",
  "shipping_update_description": "2026-07-01T00:00:00Z",
  "payment_collection_email_subject": "string",
  "payment_collection_email_header": "string",
  "payment_collection_email_description": "string",
  "payment_collection_email_button_text": "Preorder now",
  "klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
  "klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/notifications/{locale}', json=payload)
data = response.json()
Request Body
{
  "preorder_email_enabled": true,
  "preorder_sms_enabled": true,
  "preorder_cancellation_enabled": true,
  "notify_payment_collection_enabled": true,
  "email_provider": "stoq",
  "sms_provider": "twilio",
  "email_from_name": "Summer Sneaker Drop",
  "shipping_update_subject": "2026-07-01T00:00:00Z",
  "shipping_update_header": "2026-07-01T00:00:00Z",
  "shipping_update_description": "2026-07-01T00:00:00Z",
  "payment_collection_email_subject": "string",
  "payment_collection_email_header": "string",
  "payment_collection_email_description": "string",
  "payment_collection_email_button_text": "Preorder now",
  "klaviyo_shipping_update_flow_name": "Summer Sneaker Drop",
  "klaviyo_payment_failed_flow_name": "Summer Sneaker Drop"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Preorders · Offer Lookup

Find

GET
https://app.stoqapp.com/api/v2/external/preorders/offer_lookup

Resolve one preorder offer from an exact id or a fuzzy name match. Returns the full offer (same shape as GET /preorders/offers/:id) on a unique match. If name matches more than one offer, returns {ambiguous: true, candidates: [...]} instead of guessing -- re-call with the chosen id. Omit both id and name for the most recently created offer.

Parameters

idanyquery
nameanyquery

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Find
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/offer_lookup'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offer_lookup', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offer_lookup')
data = response.json()
{}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Preorders · Offers

List

GET
https://app.stoqapp.com/api/v2/external/preorders/offers

List preorder offers in this shop, paginated. search matches offer name, internal name, or an attached product's title. status filters by enabled/disabled/scheduled. market_ids narrows to offers restricted to those Shopify markets. sort orders by created date, name, or revenue.

Note: expand adds capability blocks to each row, in the same shape as their own reads: inventory, shipping, payments, markets, products (comma-separated or an array). summary counts every offer matching the filters by state (total, active, scheduled, paused, ended), not only this page.

Parameters

statusanyallenableddisabledscheduledquery
sortanycreated_at desccreated_at ascinternal_name ascinternal_name descpreorder_revenue descpreorder_revenue ascquery
pageanyquery
per_pageanyquery
searchanyquery
market_idsanyquery
expandanyquery

Response

200OKobject

Success — example response shown.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

List
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

POST
https://app.stoqapp.com/api/v2/external/preorders/offers

Create a new preorder offer.

Body

application/json
nameany
internal_nameany

Response

200OKobject

Success — example response shown.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Create
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}

Read a preorder offer's full representation.

Parameters

idstringrequiredpath

Response

200OKobject

Success — example response shown.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Read
curl -X GET 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}', {
  method: 'GET',
});

const data = await response.json();
import requests

response = requests.get('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}')
data = response.json()
{
  "id": "gid://shopify/SellingPlan/1",
  "name": "Summer Sneaker Drop",
  "internal_name": "summer-2026",
  "status": "active",
  "created_at": "2026-06-25T10:30:45Z",
  "updated_at": "2026-06-25T11:45:30Z",
  "variants": {
    "count": 3,
    "url": "/api/v2/external/preorders/offers/1/products/variants"
  },
  "products": {
    "source": "custom",
    "custom": {
      "variant_ids_sample": [
        47284734423096,
        47284734455864,
        47284734488632
      ]
    }
  },
  "widget": {
    "button": {
      "text": "Preorder Now",
      "colors": {
        "enabled": true,
        "text_color": "#FFFFFF",
        "background_color": "#1a1a1a"
      }
    },
    "disclaimer": {
      "enabled": true,
      "text": "Expected to ship by August 2026",
      "text_color": "#666666",
      "background_color": "#F5F5F5",
      "border_radius": "4px"
    },
    "badge": {
      "enabled": true,
      "text": "Pre-Order",
      "text_color": "#FFFFFF",
      "background_color": "#FF6B35"
    }
  },
  "shipping": {
    "delivery": {
      "applies_to_all_products": true,
      "type": "on_date",
      "days": null,
      "date": "2026-08-15T00:00:00Z"
    },
    "display": {
      "show_details": true,
      "shipping_text": "Ships in August 2026",
      "shipping_line_item_property_enabled": true
    }
  },
  "payments": {
    "mode": "full",
    "discount": {
      "type": null,
      "value": null
    },
    "options": [
      {
        "type": "full",
        "deposit_percent": null
      }
    ]
  },
  "limits": {
    "per_order": {
      "min": 1,
      "max": 5
    },
    "per_customer": {
      "max": 2
    },
    "total": {
      "max": 500,
      "current_count": null
    },
    "display": {
      "show_remaining": true,
      "quantity_limit_text": "Only 500 available"
    }
  },
  "checkout": {
    "terms": {
      "enabled": true,
      "text": "I understand this is a pre-order and will ship in August",
      "disable_button_until_acknowledged": true
    },
    "mixed_cart": {
      "allowed": false,
      "error_message": "Pre-orders cannot be mixed with regular items"
    },
    "order_tags": {
      "tags": [
        "preorder",
        "summer-2026"
      ]
    }
  },
  "inventory": {
    "provider": "stoq",
    "reservation": {
      "timing": "on_sale"
    },
    "continue_selling": {
      "enabled": true,
      "auto_apply_to_new_variants": true
    }
  },
  "markets": {
    "enabled": false,
    "applies_to_all_markets": false,
    "market_ids": []
  },
  "countdown": {
    "enabled": true,
    "mode": "to_schedule_end",
    "format": "d:h:m:s",
    "text": "Offer ends in"
  },
  "integrations": {
    "pos": {
      "enabled": true,
      "skip_inventory_check": false
    },
    "b2b": {
      "enabled": false
    }
  },
  "translations": {
    "default_locale": "en",
    "locales": [
      "en",
      "fr"
    ],
    "fields": [
      "widget.button.text"
    ],
    "translations": {
      "fr": {
        "widget.button.text": "Pré-commander"
      }
    }
  },
  "advanced": {
    "use_shopify_selling_plan": false,
    "custom_css": ".preorder-badge { font-weight: bold; }"
  }
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

PATCH
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}

Update top-level fields of a preorder offer.

Body

application/json
nameany
internal_nameany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Update
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced

Read power-user settings for a preorder offer (line item properties, button text overrides, Shopify selling plan attachment).

Parameters

idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Advanced
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

PATCH
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced

Update advanced (power-user) settings on a preorder offer.

Note: Deep partial. Toggles and clears are done via this PATCH: the line-item-property toggles are line_item_properties.include_shipping_text, .include_payment_breakdown, and .include_acknowledgement (true/false each). button_text_overrides is deep-partial per state — send null to clear an override for one state, e.g. { "button_text_overrides": { "out_of_stock": null } } removes that override (the read shape still emits all three states, with null for unset). sending an empty string or null.

Body

application/json
line_item_propertiesany
button_text_overridesany
use_shopify_selling_planany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Advanced
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced' \
  -H 'Content-Type: application/json' \
  -d '{
    "line_item_properties": "string",
    "button_text_overrides": "Preorder now",
    "use_shopify_selling_plan": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "line_item_properties": "string",
      "button_text_overrides": "Preorder now",
      "use_shopify_selling_plan": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "line_item_properties": "string",
  "button_text_overrides": "Preorder now",
  "use_shopify_selling_plan": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced', json=payload)
data = response.json()
Request Body
{
  "line_item_properties": "string",
  "button_text_overrides": "Preorder now",
  "use_shopify_selling_plan": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Advanced Attach To Shopify Selling Plan

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/attach_to_shopify_selling_plan

Re-attach the offer to a Shopify selling plan group (resume syncing).

Note: Refused while "Move preorder items to a separate order" is on (shipping fulfillment.split.type 'orders'): the Shopify purchase option can't be used with separate orders. Turn that off first.

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Advanced Attach To Shopify Selling Plan
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

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/detach_from_shopify_selling_plan

Detach the offer from Shopify selling plan groups; Stoq continues to manage it via the storefront integration.

Note: Strongly discouraged for most merchants. Breaks Shopify-native integrations like checkout selling plan display and third-party subscription apps. Does not delete the existing Shopify selling plan group — it just stops syncing. Also resets what needs the purchase option: partial payment to full payment, the discount to none, and a Scheduled fulfillment status to On hold. The response lists them in also_changed.

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Advanced Detach From Shopify Selling Plan
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 Button Text Override

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_button_text_override

Override the widget button text for one state (before_launch, after_launch, or out_of_stock).

Body

application/json
stateanybefore_launchafter_launchout_of_stockrequired
textanyrequired

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Advanced Set Button Text Override
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_button_text_override' \
  -H 'Content-Type: application/json' \
  -d '{
    "state": "before_launch",
    "text": "Preorder now"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_button_text_override', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "state": "before_launch",
      "text": "Preorder now"
    }),
});

const data = await response.json();
import requests

payload = {
  "state": "before_launch",
  "text": "Preorder now"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_button_text_override', json=payload)
data = response.json()
Request Body
{
  "state": "before_launch",
  "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"
  ]
}

Advanced Set Custom Line Item Property

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/advanced/set_custom_line_item_property

Set a free-text custom line item property added to every preorder cart line.

Body

application/json
textany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Advanced Set Custom Line Item Property
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout

Read checkout settings for a preorder offer.

Parameters

idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout
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

PATCH
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/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

application/json
termsany
mixed_cartany
order_tagsany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout
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()
Request Body
{
  "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

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/add_order_tag

Add a tag to the set applied to orders containing this offer.

Body

application/json
taganyrequired

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout Add Order Tag
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()
Request Body
{
  "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

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/remove_order_tag

Remove a tag from the set applied to orders containing this offer.

Body

application/json
taganyrequired

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout Remove Order Tag
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()
Request Body
{
  "tag": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Checkout Set Mixed Cart Allowed

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_allowed

Allow or block carts that mix preorder and regular items.

Body

application/json
allowedbooleanrequired

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout Set Mixed Cart Allowed
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_allowed' \
  -H 'Content-Type: application/json' \
  -d '{
    "allowed": true
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_allowed', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "allowed": true
    }),
});

const data = await response.json();
import requests

payload = {
  "allowed": True
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_allowed', json=payload)
data = response.json()
Request Body
{
  "allowed": true
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Checkout Set Mixed Cart Error Message

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_mixed_cart_error_message

Set the error message shown when a blocked mixed cart reaches checkout.

Body

application/json
messageanyrequired

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout Set Mixed Cart Error Message
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()
Request Body
{
  "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 Order Tags

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_order_tags

Replace the set of tags applied to orders containing this offer.

Body

application/json
tagsany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout Set Order Tags
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_order_tags' \
  -H 'Content-Type: application/json' \
  -d '{
    "tags": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_order_tags', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "tags": "string"
    }),
});

const data = await response.json();
import requests

payload = {
  "tags": "string"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_order_tags', json=payload)
data = response.json()
Request Body
{
  "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 Set Terms Settings

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_settings

Require (or stop requiring) customers to accept preorder terms, with optional button-lock and acceptance-timestamp recording.

Body

application/json
enabledbooleanrequired
disable_button_untilany
record_timestampany
timestamp_labelany

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout Set Terms Settings
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_settings' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled": true,
    "disable_button_until": "string",
    "record_timestamp": "string",
    "timestamp_label": "Preorder now"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_settings', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "enabled": true,
      "disable_button_until": "string",
      "record_timestamp": "string",
      "timestamp_label": "Preorder now"
    }),
});

const data = await response.json();
import requests

payload = {
  "enabled": True,
  "disable_button_until": "string",
  "record_timestamp": "string",
  "timestamp_label": "Preorder now"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_settings', json=payload)
data = response.json()
Request Body
{
  "enabled": true,
  "disable_button_until": "string",
  "record_timestamp": "string",
  "timestamp_label": "Preorder now"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Checkout Set Terms Text

POST
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/checkout/set_terms_text

Set the terms-acceptance text shown next to the checkbox.

Body

application/json
textanyrequired

Parameters

idstringrequiredpath

Response

200OKobject

Success — the updated resource.

202AcceptedJobAccepted

Accepted — async/bulk work was queued. Poll the returned job.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.

Checkout Set Terms Text
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()
Request Body
{
  "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

GET
https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown

Read the countdown timer configuration for a preorder offer.

Parameters

idstringrequiredpath

Response

200OKobject

Success — the requested resource.

401UnauthorizedError

Missing or invalid X-Auth-Token.

404Not FoundError

The resource does not exist for this shop, or the action path is not registered.

422Unprocessable EntityError

The request failed validation.

429Too Many RequestsError

Rate limited — cost-weighted per token (read 1, write 2; 360 points / 60s). Check Retry-After.

Authorization

ApiKeyAuthapiKey in header

Send your shop’s STOQ API key in the X-Auth-Token header on every request. Find it in the STOQ app under Settings → Integrations → API Key. The key resolves the shop context; the same scheme is used by the MCP server and the v1 API.