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; 40 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 · 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; 40 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; 40 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.

Parameters

filteranyallpreorderback_in_stockquery
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; 40 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 · Settings

Read

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

One settings section: label, description, and its settings. Sections: delivery_settings, signup_widget, notification_channels, notification_templates, preorder_notifications, 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; 40 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 · 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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 stopped by plan limits (with blocked_reason).

Parameters

channelanyemailsmspushquery
statusanysentblockedquery
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; 40 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; 40 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, or email.

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; 40 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. Filter with shopify_product_id, shopify_variant_id, or overrides_only=true.

Parameters

shopify_product_idanyquery
shopify_variant_idanyquery
overrides_onlyanyquery
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; 40 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.

Note: Bulk-safe: a single call may address up to 100 targets and writes them in one transaction with the Shopify metafield syncs fired once for the whole batch. Targets that STOQ has no product_variants row for are reported in unmatched rather than created. Deleting a back-in-stock template clears it from every product/variant it was assigned to (they fall back to the global design); template CRUD lives on the templates capability.

Body

application/json
targetsany
button_visibilityany
restock_messageany
templateany
enable_customizationany
automatic_alerts_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; 40 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
  }'
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
    }),
});

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
}

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
}
{}
{
  "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; 40 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; 40 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 and the revenue recovered.

Parameters

fromanyquery
toanyquery
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; 40 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; 40 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; 40 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; 40 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).

Parameters

fromanyquery
toanyquery
variant_idanyquery
product_idanyquery
channelanyquery
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; 40 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; 40 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 by back-in-stock demand (pending/total signups, last requested).

Parameters

fromanyquery
toanyquery
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; 40 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; 40 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).

Parameters

fromanyquery
toanyquery
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; 40 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; 40 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

High-level overview of back-in-stock activity over a date window.

Parameters

fromanyquery
toanyquery
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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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.

Body

application/json
signups_thresholdany
signup_alertsany
scheduled_reportsany
notify_on_alert_sentany

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; 40 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"
  }'
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"
    }),
});

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

payload = {
  "signups_threshold": "string",
  "signup_alerts": "string",
  "scheduled_reports": "string",
  "notify_on_alert_sent": "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"
}
{}
{
  "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; 40 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.

Note: Channel toggles are set via this PATCH: email.enabled, sms.enabled, push.enabled — e.g. { sms: { enabled: true } }. Enabling SMS for the first time triggers a restricted-content verification check; sends may be held until the shop is verified.

Body

application/json
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; 40 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; 40 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; 40 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; 40 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).

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.

Body

application/json
batchingany
stock_thresholdany
locationsany
any_variantany

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; 40 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"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/settings/delivery', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "batching": "string",
      "stock_threshold": "string",
      "locations": "string",
      "any_variant": "string"
    }),
});

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

payload = {
  "batching": "string",
  "stock_threshold": "string",
  "locations": "string",
  "any_variant": "string"
}

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

Tagging

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; 40 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; 40 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; 40 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 accepts only "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). 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, form.copy, form.messages, form.style, form.fields, optin, branding. This capability intentionally cannot write js_config, css_config, DOM selectors/containers, inline-form settings, the app proxy path prefix or the button disable tags — those can break the storefront for every shopper. 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

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; 40 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"
  }'
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"
    }),
});

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

payload = {
  "locale": "fr",
  "button": "string",
  "placement": "string",
  "form": "string",
  "optin": "string",
  "branding": "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"
}
{}
{
  "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 EITHER field with one term (use email/phone instead to match only one).

Parameters

channelanyemailsmspushquery
statusanypendingnotifiedunsubscribedquery
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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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/{position}/{locale}

Read a localized back-in-stock notification template: position 0 is the initial alert and position 1 is the reminder.

Parameters

positionstringrequiredpath
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; 40 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/{position}/{locale}'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{position}/{locale}', {
  method: 'GET',
});

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

response = requests.get('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{position}/{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/{position}/{locale}

Update a localized back-in-stock notification template: position 0 is the initial alert and position 1 is the reminder. email_button_destination and sms_link_destination each accept only "checkout" or "product".

Note: Deep partial over notification-copy fields. Rejects HTML and runs Template validations and callbacks. email_button_destination and sms_link_destination each accept only "checkout" or "product" (product page).

Body

application/json
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

Parameters

positionstringrequiredpath
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; 40 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/{position}/{locale}' \
  -H 'Content-Type: application/json' \
  -d '{
    "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"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{position}/{locale}', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "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"
    }),
});

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

payload = {
  "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"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/back_in_stock/templates/{position}/{locale}', json=payload)
data = response.json()
Request Body
{
  "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"
}
{}
{
  "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 · Notifications

Read

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

Read shop-level preorder notification settings for a locale.

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; 40 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
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
email_from_namestring
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; 40 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",
    "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",
    "email_from_name": "Summer Sneaker Drop",
    "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",
      "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",
      "email_from_name": "Summer Sneaker Drop",
      "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",
  "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",
  "email_from_name": "Summer Sneaker Drop",
  "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",
  "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",
  "email_from_name": "Summer Sneaker Drop",
  "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; 40 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.

Parameters

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

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; 40 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; 40 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; 40 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_shipping_timeline": true,
      "shipping_text": "Ships in August 2026",
      "shipping_line_item_property_enabled": true
    }
  },
  "payments": {
    "mode": "full",
    "discount": {
      "type": null,
      "value": null
    },
    "options": [
      {
        "type": "full",
        "deposit_percent": null
      }
    ]
  },
  "limits": {
    "per_order": {
      "min": 1,
      "max": 5
    },
    "per_customer": {
      "max": 2
    },
    "total": {
      "max": 500,
      "current_count": null
    },
    "display": {
      "show_remaining": true,
      "quantity_limit_text": "Only 500 available"
    }
  },
  "checkout": {
    "terms": {
      "enabled": true,
      "text": "I understand this is a pre-order and will ship in August",
      "disable_button_until_acknowledged": true
    },
    "mixed_cart": {
      "allowed": false,
      "error_message": "Pre-orders cannot be mixed with regular items"
    },
    "order_tags": {
      "tags": [
        "preorder",
        "summer-2026"
      ]
    }
  },
  "inventory": {
    "provider": "stoq",
    "reservation": {
      "timing": "on_sale"
    },
    "continue_selling": {
      "enabled": true,
      "auto_apply_to_new_variants": true
    }
  },
  "markets": {
    "enabled": false,
    "applies_to_all_markets": false,
    "market_ids": []
  },
  "countdown": {
    "enabled": true,
    "mode": "to_schedule_end",
    "format": "d:h:m:s",
    "text": "Offer ends in"
  },
  "integrations": {
    "pos": {
      "enabled": true,
      "skip_inventory_check": false
    },
    "b2b": {
      "enabled": false
    }
  },
  "translations": {
    "default_locale": "en",
    "locales": [
      "en",
      "fr"
    ],
    "fields": [
      "widget.button.text"
    ],
    "translations": {
      "fr": {
        "widget.button.text": "Pré-commander"
      }
    }
  },
  "advanced": {
    "use_shopify_selling_plan": false,
    "custom_css": ".preorder-badge { font-weight: bold; }"
  }
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Update

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; 40 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; 40 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; 40 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).

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; 40 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.

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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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; 40 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.

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

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

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

Countdown

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

Update countdown timer settings on a preorder offer.

Note: Deep partial. countdown.enabled is toggled via this PATCH (enabled true/false); text is an alias for ends_text — both write the same column, and an explicit ends_text wins when both are sent.

Body

application/json
enabledany
modeany
custom_end_dateany
custom_start_dateany
formatany
textany
starts_textany
ends_textany
unit_labelsany
styleany

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; 40 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.

Countdown
curl -X PATCH 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled": true,
    "mode": "string",
    "custom_end_date": "2026-07-01T00:00:00Z",
    "custom_start_date": "2026-07-01T00:00:00Z",
    "format": "string",
    "text": "Preorder now",
    "starts_text": "Preorder now",
    "ends_text": "Preorder now",
    "unit_labels": "Preorder now",
    "style": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "enabled": true,
      "mode": "string",
      "custom_end_date": "2026-07-01T00:00:00Z",
      "custom_start_date": "2026-07-01T00:00:00Z",
      "format": "string",
      "text": "Preorder now",
      "starts_text": "Preorder now",
      "ends_text": "Preorder now",
      "unit_labels": "Preorder now",
      "style": "string"
    }),
});

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

payload = {
  "enabled": True,
  "mode": "string",
  "custom_end_date": "2026-07-01T00:00:00Z",
  "custom_start_date": "2026-07-01T00:00:00Z",
  "format": "string",
  "text": "Preorder now",
  "starts_text": "Preorder now",
  "ends_text": "Preorder now",
  "unit_labels": "Preorder now",
  "style": "string"
}

response = requests.patch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown', json=payload)
data = response.json()
Request Body
{
  "enabled": true,
  "mode": "string",
  "custom_end_date": "2026-07-01T00:00:00Z",
  "custom_start_date": "2026-07-01T00:00:00Z",
  "format": "string",
  "text": "Preorder now",
  "starts_text": "Preorder now",
  "ends_text": "Preorder now",
  "unit_labels": "Preorder now",
  "style": "string"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Countdown Set Custom End Date

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

Set the custom end date for the countdown timer.

Note: Has no visible effect unless mode is to_custom_date.

Body

application/json
dateanyrequired

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; 40 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.

Countdown Set Custom End Date
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_custom_end_date' \
  -H 'Content-Type: application/json' \
  -d '{
    "date": "2026-07-01T00:00:00Z"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_custom_end_date', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "date": "2026-07-01T00:00:00Z"
    }),
});

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

payload = {
  "date": "2026-07-01T00:00:00Z"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_custom_end_date', json=payload)
data = response.json()
Request Body
{
  "date": "2026-07-01T00:00:00Z"
}
{}
{
  "job_id": "job_a1b2c3",
  "status_url": "/api/v2/external/jobs/job_a1b2c3"
}
{
  "errors": [
    "Unauthorized"
  ]
}
{
  "errors": [
    "Offer not found"
  ]
}
{
  "errors": [
    "name is required"
  ]
}
{
  "errors": [
    "Rate limit exceeded"
  ]
}

Countdown Set Ends Text

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

Set the text shown next to the countdown timer when the offer is closing.

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; 40 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.

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

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

payload = {
  "text": "Preorder now"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_ends_text', json=payload)
data = response.json()
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 Set Mode

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

Set the countdown source: 'to_schedule_end' (count down to the offer's scheduled end) or 'to_custom_date' (count down to a fixed date set via set_custom_end_date).

Body

application/json
modeanyto_schedule_endto_custom_daterequired

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; 40 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.

Countdown Set Mode
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_mode' \
  -H 'Content-Type: application/json' \
  -d '{
    "mode": "to_schedule_end"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_mode', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "mode": "to_schedule_end"
    }),
});

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

payload = {
  "mode": "to_schedule_end"
}

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

Countdown Set Starts Text

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

Set the text shown before the countdown timer when the offer hasn't started yet.

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; 40 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.

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

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

payload = {
  "text": "Preorder now"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_starts_text', json=payload)
data = response.json()
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 Set Style

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

Set the countdown timer's visual style (type, colors, border radius).

Body

application/json
typeany
text_colorany
background_colorany
border_radiusany

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; 40 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.

Countdown Set Style
curl -X POST 'https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_style' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "string",
    "text_color": "#1A1A1A",
    "background_color": "#1A1A1A",
    "border_radius": "string"
  }'
const response = await fetch('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_style', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "type": "string",
      "text_color": "#1A1A1A",
      "background_color": "#1A1A1A",
      "border_radius": "string"
    }),
});

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

payload = {
  "type": "string",
  "text_color": "#1A1A1A",
  "background_color": "#1A1A1A",
  "border_radius": "string"
}

response = requests.post('https://app.stoqapp.com/api/v2/external/preorders/offers/{id}/countdown/set_style', json=payload)
data = response.json()