Home

STOQ API v1

v1.0.0

Contact: support@stoqapp.com

Base URL
https://app.stoqapp.com/api/v1Production

Back in Stock

Before diving into the API reference, it's important to understand the key term we use - Intent

Intents are essentially "waitlist requests" or "subscriptions" that customers create when they want to be notified with a back in stock alert.

  1. Core Purpose:
    • When a product is out of stock, customers can sign up to be notified when it becomes available again
    • Each intent represents a single customer's request to be notified about a specific product variant.
    • Intent is unique to a customer, product variant & market.
  2. What data is present in an Intent?
    • Customer Information: Each intent contains customer details like email, phone, and name
    • Product Information: Shopify product and product variant IDs
    • Notification Preference: Specifies how the customer wants to be notified (email or SMS)
    • Quantity: How many units the customer is interested in when the product is back in stock
  3. Lifecycle of an Intent:
    • Created when a customer signs up for notifications
    • Can be notified when the product becomes available
    • Can be blocked from sending notifications
    • Can be unsubscribed by the customer
    • Tracks notification history and opt-in status
  4. Compliance & Privacy:
    • Includes GDPR opt-in confirmation tracking
    • Tracks marketing preferences
    • Maintains unsubscribe status

Preorders

Before diving into the API reference, it's important to understand the key term we use - Selling Plans

What are Selling Plans?

Selling Plans in the context of preorders are configurations that define how a preorder product is sold, billed, and delivered to customers.

Core Purpose:

  • Enable merchants to sell products before they're in stock or available for immediate shipping
  • Define payment schedules, delivery timelines, and inventory management for preordered items
  • Provide customization options for how preorders appear and function in the storefront

What data is present in a Selling Plan?

  • Basic Information: Name, internal reference name, enabled status
  • Billing Configuration: When and how much to charge (at checkout or later), charge types (percentage or fixed amount)
  • Delivery Settings: When products will be delivered (exact date or interval after purchase)
  • Inventory Management: How inventory is reserved and which system manages it
  • Pricing Options: Discount amounts or percentages for preordered items
  • UI Customization: Button text, badge styling, shipping information text

Variant Association:

  • Selling plans can be associated with product variants in three ways:
    • All products in the store
    • Products in a specific collection
    • Custom selection of individual variants
  • Each variant can have custom settings like shipping text and maximum preorder quantity

Multi-Market Support:

  • Selling plans can be configured for specific markets in multi-market stores
  • Different markets may have different preorder terms or availability

Authentication

ApiKeyAuthapiKey

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

API Key: X-Auth-Token in header

Back in Stock

Create Customer Intent to Buy Product

POST
https://app.stoqapp.com/api/v1/intents.json

Create a new intent for a customer to be notified when a product is back in stock. Unlike other API endpoints for Back in Stock, this API endpoint does not require an API Key.

Body

application/json
intentobjectrequired
Show child attributes
shopify_variant_idintegerrequired

The ID for the Shopify Variant

shopify_product_idintegerrequired

The ID for the Shopify Product

shopify_market_idinteger

The ID for the Shopify Market (for multi-market stores)

channelstringemailsmspushrequired

The notification channel (email requires customer.email, sms requires customer.phone, push requires customer.push)

quantityintegerrequired

The quantity of the Variant they want

sourcestringapirequired

Should be set to 'api'

customerobjectrequired
Show child attributes
idstring

Optional customer id from previous API call response

namestring

Customer's name (Shop must be on standard plan or above)

emailstring

Customer email address (required if channel is email)

phonestring

Customer phone number with country code but without '+' (required if channel is sms)

pushstring

Push notification token (required if channel is push)

country_codestring

Country code for the customer phone number

countrystring

Country in two letter code for the customer (improves phone number validation)

accepts_marketingboolean

Whether the customer has agreed to receive email content from your online store

localestring

Customer locale

shopify_market_idinteger

Customer's Shopify Market ID for multi-market stores

shopify_customer_idstring

Customer's Shopify ID

productobject

Product data is only needed if you have optin confirmation or alerts to your shop set up

Show child attributes
variant_countinteger

The number of variants the Shopify Product has

titlestring

The title for the Shopify Product

variant_titlestring

The title for the Shopify Variant

vendorstring

The vendor/brand of the product

skustring

The SKU of the variant

Parameters

X-Shopify-Shop-Domainstringrequiredheader

The Shopify shop domain (e.g. 'restock-rocket-demo.myshopify.com')

Content-Typestringapplication/jsonrequiredheader

Must be application/json

Response

200OKobject

Request processed but with errors

201Createdobject

Intent created successfully

400Bad Request

Bad request

401Unauthorized

Unauthorized

Create Customer Intent to Buy Product
curl -X POST 'https://app.stoqapp.com/api/v1/intents.json' \
  -H 'Content-Type: application/json' \
  -d '{
    "intent": {
      "shopify_variant_id": 43900910010503,
      "shopify_product_id": 7891234567890,
      "channel": "email",
      "quantity": 1,
      "source": "api"
    },
    "customer": {
      "email": "shopper@example.com",
      "name": "Alex Shopper",
      "accepts_marketing": true,
      "country": "us"
    }
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/intents.json', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "intent": {
        "shopify_variant_id": 43900910010503,
        "shopify_product_id": 7891234567890,
        "channel": "email",
        "quantity": 1,
        "source": "api"
      },
      "customer": {
        "email": "shopper@example.com",
        "name": "Alex Shopper",
        "accepts_marketing": true,
        "country": "us"
      }
    }),
});

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

payload = {
  "intent": {
    "shopify_variant_id": 43900910010503,
    "shopify_product_id": 7891234567890,
    "channel": "email",
    "quantity": 1,
    "source": "api"
  },
  "customer": {
    "email": "shopper@example.com",
    "name": "Alex Shopper",
    "accepts_marketing": True,
    "country": "us"
  }
}

response = requests.post('https://app.stoqapp.com/api/v1/intents.json', json=payload)
data = response.json()
Request Body
{
  "intent": {
    "shopify_variant_id": 43900910010503,
    "shopify_product_id": 7891234567890,
    "channel": "email",
    "quantity": 1,
    "source": "api"
  },
  "customer": {
    "email": "shopper@example.com",
    "name": "Alex Shopper",
    "accepts_marketing": true,
    "country": "us"
  }
}
{
  "errors": [
    "string"
  ]
}
{
  "intents": [
    {
      "id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
      "channel": "email",
      "email": "shopper@example.com",
      "phone": null,
      "quantity": 1,
      "notified_at": null,
      "optin_confirmed": true,
      "source": "api",
      "type": "restock",
      "sent_notifications_count": 0,
      "created_at": "2026-06-20T14:30:00Z",
      "updated_at": "2026-06-20T14:30:00Z",
      "customer_id": "c1d2e3f4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
      "shop_id": "a1b2c3d4-5e6f-7081-92a3-b4c5d6e7f809",
      "shopify_product_id": 7891234567890,
      "shopify_variant_id": 43900910010503,
      "accepts_marketing": true
    }
  ],
  "errors": []
}

Delete intents (single or multiple)

DELETE
https://app.stoqapp.com/api/v1/intents/bulk_destroy

Delete one or more intents by their IDs. Only intents that have not been sent (notified_at is null) can be deleted. If any of the intents have been sent, the entire operation will fail and return a 422 error with the IDs of sent intents. You can pass a single intent ID in the array to delete just one intent.

Body

application/json
intent_idsArray<string>required

Array of intent IDs to delete

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

Response

200OKobject

All intents deleted successfully

400Bad Requestobject

Bad request - invalid parameters

401Unauthorized

Unauthorized

404Not Foundobject

No valid intents found

422Unprocessable Entityobject

Cannot delete intents that have already been sent

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Delete intents (single or multiple)
curl -X DELETE 'https://app.stoqapp.com/api/v1/intents/bulk_destroy' \
  -H 'Content-Type: application/json' \
  -d '{
    "intent_ids": [
      "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
      "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
    ]
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/intents/bulk_destroy', {
  method: 'DELETE',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "intent_ids": [
        "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
        "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
      ]
    }),
});

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

payload = {
  "intent_ids": [
    "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
    "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
  ]
}

response = requests.delete('https://app.stoqapp.com/api/v1/intents/bulk_destroy', json=payload)
data = response.json()
Request Body
{
  "intent_ids": [
    "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
    "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
  ]
}
{
  "success": true,
  "deleted_count": 2
}
{
  "error": "string"
}
{
  "error": "string"
}
{
  "error": "string",
  "sent_intent_ids": [
    "string"
  ]
}

Get a specific intent

GET
https://app.stoqapp.com/api/v1/intents/{id}

Retrieve a single back-in-stock intent (signup) by its STOQ ID. Returns the full intent record — the customer contact details, channel, requested quantity, and notification status. Returns 404 if no intent with that ID exists for the authenticated shop.

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Intent ID

Response

200OKIntent

Intent details

401Unauthorized

Unauthorized

404Not Found

Intent not found

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Get a specific intent
curl -X GET 'https://app.stoqapp.com/api/v1/intents/{id}'
const response = await fetch('https://app.stoqapp.com/api/v1/intents/{id}', {
  method: 'GET',
});

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

response = requests.get('https://app.stoqapp.com/api/v1/intents/{id}')
data = response.json()
200
{
  "id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
  "channel": "email",
  "email": "shopper@example.com",
  "phone": null,
  "quantity": 1,
  "notified_at": null,
  "optin_confirmed": true,
  "source": "api",
  "type": "restock",
  "sent_notifications_count": 0,
  "created_at": "2026-06-20T14:30:00Z",
  "updated_at": "2026-06-20T14:30:00Z",
  "customer_id": "c1d2e3f4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
  "shop_id": "a1b2c3d4-5e6f-7081-92a3-b4c5d6e7f809",
  "shopify_product_id": 7891234567890,
  "shopify_variant_id": 43900910010503,
  "accepts_marketing": true
}

Get products in demand report

GET
https://app.stoqapp.com/api/v1/intents/products_in_demand

Retrieve a paginated list of product variants with demand metrics based on customer intents. Returns aggregated data showing total intents, pending intents, and last requested date for each variant. Results can be filtered by date range and sorted by different metrics.

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

start_datestring<date>query

Filter by start date (YYYY-MM-DD). Filters based on last_requested_at field.

end_datestring<date>query

Filter by end date (YYYY-MM-DD). Filters based on last_requested_at field.

sort_bystringpendingtotallast_requested_atpendingquery

Sort results by pending intents, total intents, or last requested date

directionstringascdescdescquery

Sort direction (ascending or descending)

pageinteger1query

Page number for pagination

per_pageinteger<= 50025query

Number of items per page (maximum 500)

intent_typestringquery

Filter by intent type (used when loading product data)

Response

200OKobject

A paginated list of product variants with demand metrics

400Bad Requestobject

Bad request - invalid parameters

401Unauthorized

Unauthorized

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Get products in demand report
curl -X GET 'https://app.stoqapp.com/api/v1/intents/products_in_demand'
const response = await fetch('https://app.stoqapp.com/api/v1/intents/products_in_demand', {
  method: 'GET',
});

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

response = requests.get('https://app.stoqapp.com/api/v1/intents/products_in_demand')
data = response.json()
{
  "product_variants_in_demand": [
    {
      "shopify_variant_id": 43900910010503,
      "shopify_product_id": 7891234567890,
      "total": 42,
      "pending": 37,
      "last_requested_at": "2026-06-24T09:12:00Z",
      "variant_data": {
        "id": 43900910010503,
        "title": "Medium / Red",
        "sku": "TSHIRT-M-RED"
      },
      "product_data": {
        "id": 7891234567890,
        "title": "Classic T-Shirt",
        "vendor": "Acme"
      }
    }
  ],
  "page": 1,
  "per_page": 25,
  "has_next_page": true,
  "has_prev_page": false
}
{
  "error": "string"
}

List and filter intents

GET
https://app.stoqapp.com/api/v1/intents

List back-in-stock intents (signups) for the shop, newest first. Supports filtering by Shopify product or variant, customer email or phone, creation date range, and notification status, with page-based pagination (up to 500 per page). Returns the matching intents alongside pagination metadata.

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

shopify_variant_idintegerquery

Filter by Shopify Variant ID

shopify_product_idintegerquery

Filter by Shopify Product ID

emailstringquery

Filter by customer email

phonestringquery

Filter by customer phone

start_datestring<date>query

Filter by start date (YYYY-MM-DD)

end_datestring<date>query

Filter by end date (YYYY-MM-DD)

notifiedbooleanquery

Filter by notification status (true = notified, false = not notified)

pageintegerquery

Page number for pagination

per_pageintegerquery

Number of items per page (maximum 500)

Response

200OKobject

A paginated list of intents

400Bad Request

Bad request

401Unauthorized

Unauthorized

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

List and filter intents
curl -X GET 'https://app.stoqapp.com/api/v1/intents'
const response = await fetch('https://app.stoqapp.com/api/v1/intents', {
  method: 'GET',
});

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

response = requests.get('https://app.stoqapp.com/api/v1/intents')
data = response.json()
200
{
  "intents": [
    {
      "id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
      "channel": "email",
      "email": "shopper@example.com",
      "phone": null,
      "quantity": 1,
      "notified_at": null,
      "optin_confirmed": true,
      "source": "api",
      "type": "restock",
      "sent_notifications_count": 0,
      "created_at": "2026-06-20T14:30:00Z",
      "updated_at": "2026-06-20T14:30:00Z",
      "customer_id": "c1d2e3f4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
      "shop_id": "a1b2c3d4-5e6f-7081-92a3-b4c5d6e7f809",
      "shopify_product_id": 7891234567890,
      "shopify_variant_id": 43900910010503,
      "accepts_marketing": true
    }
  ],
  "meta": {
    "total_count": 128,
    "page": 1,
    "per_page": 25,
    "total_pages": 6
  }
}

Notify a single intent

POST
https://app.stoqapp.com/api/v1/intents/notify_intent

Send the back-in-stock notification for a single intent immediately, regardless of current inventory. By default an intent that has already been notified will not be sent again; set allow_resend to true to force a resend. Returns 404 if the intent does not exist and 422 if the notification could not be sent.

Body

application/json
idstring

Intent ID

allow_resendboolean

Allow resending notification

Response

200OKobject

Notification sent successfully

401Unauthorized

Unauthorized

404Not Found

Intent not found

422Unprocessable Entity

Failed to notify intent

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Notify a single intent
curl -X POST 'https://app.stoqapp.com/api/v1/intents/notify_intent' \
  -H 'Content-Type: application/json' \
  -d '{
    "id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
    "allow_resend": false
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/intents/notify_intent', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
      "allow_resend": false
    }),
});

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

payload = {
  "id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
  "allow_resend": False
}

response = requests.post('https://app.stoqapp.com/api/v1/intents/notify_intent', json=payload)
data = response.json()
Request Body
{
  "id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
  "allow_resend": false
}
200
{
  "success": true,
  "intent_id": "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70"
}

Notify multiple intents in bulk

POST
https://app.stoqapp.com/api/v1/intents/bulk_notify_intent

Send back-in-stock notifications for multiple intents in one request. Each intent is processed independently; the response reports which succeeded and which failed, returning 207 when only some succeed. Set allow_resend to true to re-notify intents that were already sent.

Body

application/json
intent_idsArray<string>

Array of intent IDs

allow_resendboolean

Allow resending notifications

Response

200OKobject

All notifications sent successfully

207object

Partial success (some notifications failed)

400Bad Request

Bad request

401Unauthorized

Unauthorized

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Notify multiple intents in bulk
curl -X POST 'https://app.stoqapp.com/api/v1/intents/bulk_notify_intent' \
  -H 'Content-Type: application/json' \
  -d '{
    "intent_ids": [
      "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
      "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
    ],
    "allow_resend": false
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/intents/bulk_notify_intent', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "intent_ids": [
        "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
        "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
      ],
      "allow_resend": false
    }),
});

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

payload = {
  "intent_ids": [
    "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
    "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
  ],
  "allow_resend": False
}

response = requests.post('https://app.stoqapp.com/api/v1/intents/bulk_notify_intent', json=payload)
data = response.json()
Request Body
{
  "intent_ids": [
    "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70",
    "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809"
  ],
  "allow_resend": false
}
{
  "success": [
    "8f3c2b1a-7d4e-4c2a-9f10-2b3c4d5e6f70"
  ],
  "failed": [
    {
      "intent_id": "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809",
      "error": "Already notified"
    }
  ]
}
{
  "success": [
    "string"
  ],
  "failed": [
    {
      "intent_id": "string",
      "error": "string"
    }
  ]
}

Transfer signups from one variant to another

POST
https://app.stoqapp.com/api/v1/intents/transfer_signups

Transfer intents (signups) from a source variant to a target variant. This is useful when consolidating variants or when products are restructured. By default transfers pending intents, but can transfer sent or all intents based on intent_type parameter.

Body

application/json
from_shopify_variant_idintegerrequired

Shopify variant ID to transfer signups from

from_shopify_product_idintegerrequired

Shopify product ID of the source variant

to_shopify_variant_idintegerrequired

Shopify variant ID to transfer signups to

to_shopify_product_idintegerrequired

Shopify product ID of the target variant

intent_typestringunsentsentall

Type of intents to transfer (default is unsent/pending)

Response

200OK

Transfer completed successfully

400Bad Requestobject

Bad request - invalid parameters

401Unauthorized

Unauthorized

422Unprocessable Entityobject

Transfer failed

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Transfer signups from one variant to another
curl -X POST 'https://app.stoqapp.com/api/v1/intents/transfer_signups' \
  -H 'Content-Type: application/json' \
  -d '{
    "from_shopify_variant_id": 43900910010503,
    "from_shopify_product_id": 7891234567890,
    "to_shopify_variant_id": 43900910010999,
    "to_shopify_product_id": 7891234567890,
    "intent_type": "unsent"
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/intents/transfer_signups', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "from_shopify_variant_id": 43900910010503,
      "from_shopify_product_id": 7891234567890,
      "to_shopify_variant_id": 43900910010999,
      "to_shopify_product_id": 7891234567890,
      "intent_type": "unsent"
    }),
});

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

payload = {
  "from_shopify_variant_id": 43900910010503,
  "from_shopify_product_id": 7891234567890,
  "to_shopify_variant_id": 43900910010999,
  "to_shopify_product_id": 7891234567890,
  "intent_type": "unsent"
}

response = requests.post('https://app.stoqapp.com/api/v1/intents/transfer_signups', json=payload)
data = response.json()
Request Body
{
  "from_shopify_variant_id": 43900910010503,
  "from_shopify_product_id": 7891234567890,
  "to_shopify_variant_id": 43900910010999,
  "to_shopify_product_id": 7891234567890,
  "intent_type": "unsent"
}
{
  "error": "string"
}
{
  "errors": {}
}

Preorders

Add multiple product variants to a selling plan

POST
https://app.stoqapp.com/api/v1/external/preorders/{id}/add_variant

Attach one or more Shopify product variants to a selling plan so they become available for preorder. Pass the variant IDs in shopify_variant_ids; any that are already attached are reported back under existing_variants with a 422. Returns the list of variant IDs that were newly added.

Body

application/json
shopify_variant_idsArray<integer>required

Array of Shopify variant IDs to add

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

Response

200OKobject

Variants added successfully

400Bad Requestobject

Bad request - missing or invalid shopify_variant_ids

401Unauthorized

Unauthorized

404Not Found

Selling plan not found

422Unprocessable Entityobject

Some variants already added or other error

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Add multiple product variants to a selling plan
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders/{id}/add_variant' \
  -H 'Content-Type: application/json' \
  -d '{
    "shopify_variant_ids": [
      43900910010503,
      43900910010999
    ]
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/add_variant', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "shopify_variant_ids": [
        43900910010503,
        43900910010999
      ]
    }),
});

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

payload = {
  "shopify_variant_ids": [
    43900910010503,
    43900910010999
  ]
}

response = requests.post('https://app.stoqapp.com/api/v1/external/preorders/{id}/add_variant', json=payload)
data = response.json()
Request Body
{
  "shopify_variant_ids": [
    43900910010503,
    43900910010999
  ]
}
{
  "success": true,
  "message": "2 variants added to selling plan",
  "variants_added": [
    43900910010503,
    43900910010999
  ]
}
{
  "error": "string"
}
{
  "error": "string",
  "existing_variants": [
    0
  ]
}

List and filter selling plans

GET
https://app.stoqapp.com/api/v1/external/preorders

List the shop's preorder selling plans, newest first, with page-based pagination. Optionally filter by name (matches the display or internal name). Returns a lightweight representation of each plan plus pagination metadata; use Get a Specific Selling Plan for the full object.

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

namestringquery

Filter by selling plan name or internal name

pageintegerquery

Page number for pagination

per_pageintegerquery

Number of items per page

Response

200OKobject

A paginated list of selling plans

400Bad Request

Bad request

401Unauthorized

Unauthorized

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

List and filter selling plans
curl -X GET 'https://app.stoqapp.com/api/v1/external/preorders'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders', {
  method: 'GET',
});

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

response = requests.get('https://app.stoqapp.com/api/v1/external/preorders')
data = response.json()
200
{
  "selling_plans": [
    {
      "id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
      "name": "Summer Preorder",
      "internal_name": "summer-2026",
      "enabled": true,
      "selling_plan_product_variants_count": 12,
      "created_at": "2026-06-20T10:00:00Z",
      "updated_at": "2026-06-24T08:30:00Z",
      "shopify_variant_ids": [
        43900910010503,
        43900910010999
      ]
    }
  ],
  "meta": {
    "total_count": 3,
    "page": 1,
    "per_page": 25,
    "total_pages": 1
  }
}

Create a new selling plan

POST
https://app.stoqapp.com/api/v1/external/preorders

Create a new preorder selling plan. The selling_plan object defines billing, delivery, discount, button, badge, and fulfillment behavior; only the fields you set are applied and the rest fall back to defaults. Returns the created selling plan, including its STOQ ID, on success.

Body

application/json
selling_planSellingPlanInput

Input schema for creating or updating selling plans

Show child attributes
namestring

Display name of the selling plan

internal_namestring

Internal name for the selling plan

enabledboolean

Whether the selling plan is enabled

billing_typestringexact_timeno_remaining_balancetime_after_checkout

Type of billing for the selling plan

billing_atstring<date-time>

Exact billing time if billing_type is exact_time

billing_after_n_intervalsinteger

Number of intervals after checkout to bill

billing_after_interval_typestringday

Type of interval for billing

billing_checkout_charge_amountnumber

Fixed amount to charge at checkout

billing_checkout_charge_percentagenumber

Percentage to charge at checkout

billing_checkout_charge_typestringpercentageprice

Type of checkout charge

billing_titlestring

Title for billing section

billing_descriptionstring

Description for billing section

delivery_typestringanchorasapexact_timeunknown

Type of delivery for the selling plan

delivery_atstring<date-time>

Exact delivery time if delivery_type is exact_time

delivery_after_n_intervalsinteger

Number of intervals after checkout for delivery

delivery_after_interval_typestringday

Type of interval for delivery

inventory_reserve_typestringon_saleon_fulfillment

When to reserve inventory

inventory_providerstringstoqshopify

Inventory provider

pricing_typestringpercentagepricefixed_amountno_discount

Type of pricing discount

pricing_amountnumber

Fixed discount amount

pricing_percentagenumber

Percentage discount

quantity_limit_textstring

Text to display for quantity limits

preorder_button_textstring

Text for the preorder button

preorder_button_text_colorstring

Text color for the preorder button

preorder_button_background_colorstring

Background color for the preorder button

preorder_button_colors_enabledboolean

Whether custom colors are enabled for the preorder button

preorder_discounted_price_enabledboolean

Whether to show discounted price on the preorder button

preorder_button_descriptionstring

Description text for the preorder button

preorder_button_description_background_colorstring

Background color for the preorder button description

preorder_button_description_border_radiusstring

Border radius for the preorder button description

preorder_button_description_quantity_limit_suffixstring

Suffix text for quantity limit in button description

preorder_button_description_shipping_text_prefixstring

Prefix text for shipping information in button description

preorder_button_description_show_quantity_limitboolean

Whether to show quantity limit in button description

preorder_button_description_show_shippingboolean

Whether to show shipping information in button description

preorder_button_description_text_colorstring

Text color for the preorder button description

preorder_badge_enabledboolean

Whether preorder badge is enabled

preorder_badge_textstring

Text for the preorder badge

preorder_badge_text_colorstring

Text color for the preorder badge

preorder_badge_background_colorstring

Background color for the preorder badge

preorder_shipping_textstring

Shipping text specific to preorders

shipping_textstring

Shipping information text

shipping_line_item_property_enabledboolean

Whether to enable shipping line item properties

shipping_applies_to_all_productsboolean

Whether shipping settings apply to all products

discount_textstring

Discount information text

preorder_tagsstring

Tags to apply to preorder items

product_variants_sourcestringallcollectioncustom

Source of product variants for this selling plan

product_variants_source_idinteger

ID of the source (e.g., collection ID)

markets_enabledboolean

Whether market-specific settings are enabled for this selling plan

shopify_market_idsArray<integer>

List of Shopify market IDs where this selling plan is available. Required if markets_enabled is true.

auto_collect_paymentboolean

Whether to automatically collect payment when the order is ready to fulfill

use_shopify_selling_planboolean

Whether to use Shopify's native selling plan functionality for this preorder offer. When true, this enables advanced selling plan features in Shopify.

enable_billing_widgetboolean

Whether to display the payment/billing widget on the product page

split_fulfillments_enabledboolean

Whether to enable split fulfillments for preorders. When enabled, preorder items can be shipped separately from regular items in the same order.

require_preorder_acknowledgementboolean

Whether customers must accept terms and conditions before adding a preorder item to their cart.

preorder_acknowledgement_textstring

The terms and conditions text that customers must acknowledge when require_preorder_acknowledgement is enabled.

allow_mixed_cartboolean

Whether to allow customers to mix preorder items with regular items in the same cart. When false, customers must purchase preorders separately.

mixed_cart_error_messagestring

Error message displayed to customers when they attempt to mix preorder and regular items in their cart (when allow_mixed_cart is false).

preorder_min_quantityinteger

Minimum quantity required per order for preorder items. When set, customers must purchase at least this many units.

preorder_max_quantityinteger

Maximum quantity allowed per order for preorder items. When set, customers cannot purchase more than this many units.

payment_line_item_property_enabledboolean

Whether to add payment information as a line item property (e.g., "Payment - Pay in full").

custom_line_item_property_textstring

Custom text to add as a line item property for preorder items. Useful for adding custom order notes or metadata.

auto_collect_payment_on_fulfillmentboolean

Whether to automatically collect remaining payment when the order is fulfilled (for partial payment preorders).

hold_fulfillments_enabledboolean

Whether to automatically hold fulfillments for preorder items. When enabled, fulfillments will be held until manually released.

hold_fulfillments_reason_notestring

The reason note displayed when fulfillments are held (when hold_fulfillments_enabled is true).

disable_button_until_acknowledgedboolean

Whether to disable the add to cart button until the customer acknowledges the preorder terms (when require_preorder_acknowledgement is true).

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

Response

201CreatedSellingPlan

Selling plan created successfully

401Unauthorized

Unauthorized

422Unprocessable Entityobject

Validation errors

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Create a new selling plan
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders' \
  -H 'Content-Type: application/json' \
  -d '{
    "selling_plan": {
      "name": "Summer Preorder",
      "internal_name": "summer-2026",
      "enabled": true,
      "billing_type": "time_after_checkout",
      "billing_checkout_charge_type": "percentage",
      "billing_checkout_charge_percentage": 20,
      "delivery_type": "asap",
      "pricing_type": "no_discount",
      "preorder_button_text": "Preorder now",
      "preorder_badge_enabled": true,
      "preorder_badge_text": "Preorder",
      "product_variants_source": "custom"
    }
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "selling_plan": {
        "name": "Summer Preorder",
        "internal_name": "summer-2026",
        "enabled": true,
        "billing_type": "time_after_checkout",
        "billing_checkout_charge_type": "percentage",
        "billing_checkout_charge_percentage": 20,
        "delivery_type": "asap",
        "pricing_type": "no_discount",
        "preorder_button_text": "Preorder now",
        "preorder_badge_enabled": true,
        "preorder_badge_text": "Preorder",
        "product_variants_source": "custom"
      }
    }),
});

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

payload = {
  "selling_plan": {
    "name": "Summer Preorder",
    "internal_name": "summer-2026",
    "enabled": True,
    "billing_type": "time_after_checkout",
    "billing_checkout_charge_type": "percentage",
    "billing_checkout_charge_percentage": 20,
    "delivery_type": "asap",
    "pricing_type": "no_discount",
    "preorder_button_text": "Preorder now",
    "preorder_badge_enabled": True,
    "preorder_badge_text": "Preorder",
    "product_variants_source": "custom"
  }
}

response = requests.post('https://app.stoqapp.com/api/v1/external/preorders', json=payload)
data = response.json()
Request Body
{
  "selling_plan": {
    "name": "Summer Preorder",
    "internal_name": "summer-2026",
    "enabled": true,
    "billing_type": "time_after_checkout",
    "billing_checkout_charge_type": "percentage",
    "billing_checkout_charge_percentage": 20,
    "delivery_type": "asap",
    "pricing_type": "no_discount",
    "preorder_button_text": "Preorder now",
    "preorder_badge_enabled": true,
    "preorder_badge_text": "Preorder",
    "product_variants_source": "custom"
  }
}
{
  "id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
  "name": "Summer Preorder",
  "internal_name": "summer-2026",
  "enabled": true,
  "billing_type": "time_after_checkout",
  "billing_checkout_charge_type": "percentage",
  "billing_checkout_charge_percentage": 20,
  "delivery_type": "asap",
  "pricing_type": "no_discount",
  "preorder_button_text": "Preorder now",
  "preorder_badge_enabled": true,
  "preorder_badge_text": "Preorder",
  "selling_plan_product_variants_count": 0,
  "shopify_selling_plan_id": null,
  "shopify_selling_plan_group_id": null,
  "shop_id": 43,
  "created_at": "2026-06-20T10:00:00Z",
  "updated_at": "2026-06-24T08:30:00Z",
  "ongoing_job": false,
  "shopify_variant_ids": []
}
{
  "errors": {}
}

Get a specific selling plan

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

Retrieve a single preorder selling plan by its STOQ ID, including the full billing, delivery, pricing, button, badge, fulfillment, and market configuration, the count of attached variants, and the associated Shopify selling-plan IDs. Returns 404 if no plan with that ID exists for the shop.

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

Response

200OKSellingPlan

Selling plan details

401Unauthorized

Unauthorized

404Not Found

Selling plan not found

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Get a specific selling plan
curl -X GET 'https://app.stoqapp.com/api/v1/external/preorders/{id}'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}', {
  method: 'GET',
});

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

response = requests.get('https://app.stoqapp.com/api/v1/external/preorders/{id}')
data = response.json()
200
{
  "id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
  "name": "Summer Preorder",
  "internal_name": "summer-2026",
  "enabled": true,
  "billing_type": "time_after_checkout",
  "billing_checkout_charge_type": "percentage",
  "billing_checkout_charge_percentage": 20,
  "delivery_type": "asap",
  "pricing_type": "no_discount",
  "preorder_button_text": "Preorder now",
  "preorder_badge_enabled": true,
  "preorder_badge_text": "Preorder",
  "selling_plan_product_variants_count": 12,
  "shopify_selling_plan_id": 645123456,
  "shopify_selling_plan_group_id": 9912345,
  "shop_id": 43,
  "created_at": "2026-06-20T10:00:00Z",
  "updated_at": "2026-06-24T08:30:00Z",
  "ongoing_job": false,
  "shopify_variant_ids": [
    43900910010503,
    43900910010999
  ]
}

Update a selling plan

PUT
https://app.stoqapp.com/api/v1/external/preorders/{id}

Update an existing preorder selling plan. Supply a selling_plan object with the fields you want to change; omitted fields are left unchanged. Returns the updated selling plan, or 422 with validation errors if the changes are invalid.

Body

application/json
selling_planSellingPlanInput

Input schema for creating or updating selling plans

Show child attributes
namestring

Display name of the selling plan

internal_namestring

Internal name for the selling plan

enabledboolean

Whether the selling plan is enabled

billing_typestringexact_timeno_remaining_balancetime_after_checkout

Type of billing for the selling plan

billing_atstring<date-time>

Exact billing time if billing_type is exact_time

billing_after_n_intervalsinteger

Number of intervals after checkout to bill

billing_after_interval_typestringday

Type of interval for billing

billing_checkout_charge_amountnumber

Fixed amount to charge at checkout

billing_checkout_charge_percentagenumber

Percentage to charge at checkout

billing_checkout_charge_typestringpercentageprice

Type of checkout charge

billing_titlestring

Title for billing section

billing_descriptionstring

Description for billing section

delivery_typestringanchorasapexact_timeunknown

Type of delivery for the selling plan

delivery_atstring<date-time>

Exact delivery time if delivery_type is exact_time

delivery_after_n_intervalsinteger

Number of intervals after checkout for delivery

delivery_after_interval_typestringday

Type of interval for delivery

inventory_reserve_typestringon_saleon_fulfillment

When to reserve inventory

inventory_providerstringstoqshopify

Inventory provider

pricing_typestringpercentagepricefixed_amountno_discount

Type of pricing discount

pricing_amountnumber

Fixed discount amount

pricing_percentagenumber

Percentage discount

quantity_limit_textstring

Text to display for quantity limits

preorder_button_textstring

Text for the preorder button

preorder_button_text_colorstring

Text color for the preorder button

preorder_button_background_colorstring

Background color for the preorder button

preorder_button_colors_enabledboolean

Whether custom colors are enabled for the preorder button

preorder_discounted_price_enabledboolean

Whether to show discounted price on the preorder button

preorder_button_descriptionstring

Description text for the preorder button

preorder_button_description_background_colorstring

Background color for the preorder button description

preorder_button_description_border_radiusstring

Border radius for the preorder button description

preorder_button_description_quantity_limit_suffixstring

Suffix text for quantity limit in button description

preorder_button_description_shipping_text_prefixstring

Prefix text for shipping information in button description

preorder_button_description_show_quantity_limitboolean

Whether to show quantity limit in button description

preorder_button_description_show_shippingboolean

Whether to show shipping information in button description

preorder_button_description_text_colorstring

Text color for the preorder button description

preorder_badge_enabledboolean

Whether preorder badge is enabled

preorder_badge_textstring

Text for the preorder badge

preorder_badge_text_colorstring

Text color for the preorder badge

preorder_badge_background_colorstring

Background color for the preorder badge

preorder_shipping_textstring

Shipping text specific to preorders

shipping_textstring

Shipping information text

shipping_line_item_property_enabledboolean

Whether to enable shipping line item properties

shipping_applies_to_all_productsboolean

Whether shipping settings apply to all products

discount_textstring

Discount information text

preorder_tagsstring

Tags to apply to preorder items

product_variants_sourcestringallcollectioncustom

Source of product variants for this selling plan

product_variants_source_idinteger

ID of the source (e.g., collection ID)

markets_enabledboolean

Whether market-specific settings are enabled for this selling plan

shopify_market_idsArray<integer>

List of Shopify market IDs where this selling plan is available. Required if markets_enabled is true.

auto_collect_paymentboolean

Whether to automatically collect payment when the order is ready to fulfill

use_shopify_selling_planboolean

Whether to use Shopify's native selling plan functionality for this preorder offer. When true, this enables advanced selling plan features in Shopify.

enable_billing_widgetboolean

Whether to display the payment/billing widget on the product page

split_fulfillments_enabledboolean

Whether to enable split fulfillments for preorders. When enabled, preorder items can be shipped separately from regular items in the same order.

require_preorder_acknowledgementboolean

Whether customers must accept terms and conditions before adding a preorder item to their cart.

preorder_acknowledgement_textstring

The terms and conditions text that customers must acknowledge when require_preorder_acknowledgement is enabled.

allow_mixed_cartboolean

Whether to allow customers to mix preorder items with regular items in the same cart. When false, customers must purchase preorders separately.

mixed_cart_error_messagestring

Error message displayed to customers when they attempt to mix preorder and regular items in their cart (when allow_mixed_cart is false).

preorder_min_quantityinteger

Minimum quantity required per order for preorder items. When set, customers must purchase at least this many units.

preorder_max_quantityinteger

Maximum quantity allowed per order for preorder items. When set, customers cannot purchase more than this many units.

payment_line_item_property_enabledboolean

Whether to add payment information as a line item property (e.g., "Payment - Pay in full").

custom_line_item_property_textstring

Custom text to add as a line item property for preorder items. Useful for adding custom order notes or metadata.

auto_collect_payment_on_fulfillmentboolean

Whether to automatically collect remaining payment when the order is fulfilled (for partial payment preorders).

hold_fulfillments_enabledboolean

Whether to automatically hold fulfillments for preorder items. When enabled, fulfillments will be held until manually released.

hold_fulfillments_reason_notestring

The reason note displayed when fulfillments are held (when hold_fulfillments_enabled is true).

disable_button_until_acknowledgedboolean

Whether to disable the add to cart button until the customer acknowledges the preorder terms (when require_preorder_acknowledgement is true).

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

Response

200OKSellingPlan

Selling plan updated successfully

401Unauthorized

Unauthorized

404Not Found

Selling plan not found

422Unprocessable Entityobject

Validation errors

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Update a selling plan
curl -X PUT 'https://app.stoqapp.com/api/v1/external/preorders/{id}' \
  -H 'Content-Type: application/json' \
  -d '{
    "selling_plan": {
      "enabled": false,
      "preorder_button_text": "Coming soon"
    }
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "selling_plan": {
        "enabled": false,
        "preorder_button_text": "Coming soon"
      }
    }),
});

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

payload = {
  "selling_plan": {
    "enabled": False,
    "preorder_button_text": "Coming soon"
  }
}

response = requests.put('https://app.stoqapp.com/api/v1/external/preorders/{id}', json=payload)
data = response.json()
Request Body
{
  "selling_plan": {
    "enabled": false,
    "preorder_button_text": "Coming soon"
  }
}
{
  "id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
  "name": "Summer Preorder",
  "internal_name": "summer-2026",
  "enabled": false,
  "billing_type": "time_after_checkout",
  "billing_checkout_charge_type": "percentage",
  "billing_checkout_charge_percentage": 20,
  "delivery_type": "asap",
  "pricing_type": "no_discount",
  "preorder_button_text": "Coming soon",
  "preorder_badge_enabled": true,
  "preorder_badge_text": "Preorder",
  "selling_plan_product_variants_count": 12,
  "shopify_selling_plan_id": 645123456,
  "shopify_selling_plan_group_id": 9912345,
  "shop_id": 43,
  "created_at": "2026-06-20T10:00:00Z",
  "updated_at": "2026-06-24T08:30:00Z",
  "ongoing_job": false,
  "shopify_variant_ids": [
    43900910010503,
    43900910010999
  ]
}
{
  "errors": {}
}

Delete a selling plan (soft delete)

DELETE
https://app.stoqapp.com/api/v1/external/preorders/{id}

Soft-delete a preorder selling plan by ID. The plan is discarded (its discarded_at is set) and detached from the storefront, but historical preorder data is preserved. Returns 404 if the plan does not exist and 422 if it could not be deleted.

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

Response

200OKobject

Selling plan deleted successfully

401Unauthorized

Unauthorized

404Not Found

Selling plan not found

422Unprocessable Entityobject

Failed to delete selling plan

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Delete a selling plan (soft delete)
curl -X DELETE 'https://app.stoqapp.com/api/v1/external/preorders/{id}'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}', {
  method: 'DELETE',
});

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

response = requests.delete('https://app.stoqapp.com/api/v1/external/preorders/{id}')
data = response.json()
{
  "success": true,
  "message": "Selling plan deleted"
}
{
  "error": "string"
}

Get product variants associated with a selling plan

GET
https://app.stoqapp.com/api/v1/external/preorders/{id}/product_variants

Retrieve product variants associated with a selling plan, including their preorder details and sales metrics.

Filtering behavior:

  • No parameters: Returns all product variants in the selling plan
  • shopify_product_id: Returns all variants for that specific product
  • shopify_variant_id: Returns only that specific variant (single object response)

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

shopify_product_idintegerquery

Filter by specific Shopify product ID to get all variants for that product

shopify_variant_idintegerquery

Filter by specific Shopify variant ID to get only that variant (returns single object)

Response

200OKSellingPlanProductVariantsResponse | SellingPlanSingleVariantResponse

Product variants with their preorder details and sales metrics

400Bad Requestobject

Bad request - cannot filter by both product and variant ID

401Unauthorized

Unauthorized

404Not Foundobject

Selling plan not found or variant not found in this selling plan

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Get product variants associated with a selling plan
curl -X GET 'https://app.stoqapp.com/api/v1/external/preorders/{id}/product_variants'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/product_variants', {
  method: 'GET',
});

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

response = requests.get('https://app.stoqapp.com/api/v1/external/preorders/{id}/product_variants')
data = response.json()
{
  "selling_plan_id": "79b44c6c-ebc7-41d4-8a1b-573d7c693454",
  "selling_plan_name": "Summer Preorder",
  "currency": "USD",
  "product_variants": [
    {
      "shopify_product_id": 7891234567890,
      "shopify_variant_id": 43900910010503,
      "product_title": "Classic T-Shirt",
      "variant_title": "Medium / Red",
      "preorder_units_sold": 18,
      "preorder_max_count": 100,
      "shipping_text": "Ships July 2026"
    }
  ],
  "meta": {
    "total_variants": 12,
    "total_units_sold": 140
  }
}
{
  "error": "string"
}
{
  "error": "string"
}

Remove multiple product variants from a selling plan

DELETE
https://app.stoqapp.com/api/v1/external/preorders/{id}/remove_variant

Remove multiple product variants from a selling plan. Optionally, you can also update the inventory policy of the removed variants in the same request to avoid making separate API calls.

When inventory_policy is provided, the inventory policy update is performed synchronously (inline) for better performance and to avoid race conditions.

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

shopify_variant_idsArray<integer>requiredquery

Array of Shopify variant IDs to remove

inventory_policystringCONTINUEDENYquery

Optional. Inventory policy to set for the removed variants. CONTINUE allows overselling, DENY prevents it.

Response

200OKobject

Variants removed successfully

400Bad Requestobject

Bad request - missing or invalid parameters

401Unauthorized

Unauthorized

404Not Foundobject

Selling plan or variants not found

422Unprocessable Entityobject

Failed to remove variants or invalid inventory policy

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Remove multiple product variants from a selling plan
curl -X DELETE 'https://app.stoqapp.com/api/v1/external/preorders/{id}/remove_variant'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/remove_variant', {
  method: 'DELETE',
});

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

response = requests.delete('https://app.stoqapp.com/api/v1/external/preorders/{id}/remove_variant')
data = response.json()
{
  "success": true,
  "message": "1 variant removed",
  "variants_removed": [
    43900910010503
  ],
  "inventory_policy_updated": true,
  "inventory_policy": "DENY"
}
{
  "error": "string"
}
{
  "error": "string"
}
{
  "error": "string"
}

Send shipping update emails to multiple orders

POST
https://app.stoqapp.com/api/v1/external/preorders/send_shipping_update

Send shipping update emails to multiple preorders. You can specify orders using either:

  • STOQ internal order IDs (UUIDs) via order_ids
  • Shopify order IDs via shopify_order_ids

You must provide one or the other, but not both.

Body

application/json
order_idsArray<string>

Array of STOQ internal order UUIDs to send shipping updates to (mutually exclusive with shopify_order_ids)

shopify_order_idsArray<integer>

Array of Shopify order IDs to send shipping updates to (mutually exclusive with order_ids)

subjectstringrequired

Email subject line

headerstringrequired

Email header text

descriptionstringrequired

Email body description

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

Response

200OKobject

Shipping update emails queued successfully

400Bad Requestobject

Bad request - missing required parameters or invalid input

401Unauthorized

Unauthorized

404Not Foundobject

No valid orders found

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Send shipping update emails to multiple orders
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders/send_shipping_update' \
  -H 'Content-Type: application/json' \
  -d '{
    "shopify_order_ids": [
      5012345678901,
      5012345678902
    ],
    "subject": "Your preorder has shipped",
    "header": "Good news!",
    "description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/send_shipping_update', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "shopify_order_ids": [
        5012345678901,
        5012345678902
      ],
      "subject": "Your preorder has shipped",
      "header": "Good news!",
      "description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
    }),
});

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

payload = {
  "shopify_order_ids": [
    5012345678901,
    5012345678902
  ],
  "subject": "Your preorder has shipped",
  "header": "Good news!",
  "description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
}

response = requests.post('https://app.stoqapp.com/api/v1/external/preorders/send_shipping_update', json=payload)
data = response.json()
Request Body
{
  "shopify_order_ids": [
    5012345678901,
    5012345678902
  ],
  "subject": "Your preorder has shipped",
  "header": "Good news!",
  "description": "Your Summer Preorder items are on the way and should arrive within 5–7 business days."
}
{
  "success": true,
  "message": "Shipping updates queued",
  "orders_count": 2
}
{
  "error": "string"
}
{
  "error": "string"
}

Queue a bulk update of inventory policy for multiple variants

POST
https://app.stoqapp.com/api/v1/external/preorders/{id}/bulk_toggle_inventory_policy

Queues a background job to update the inventory policy for multiple variants. The operation is performed asynchronously to handle large numbers of variants efficiently. Updates are processed in batches of up to 1000 variants to stay within message size limits.

Body

application/json
shopify_variant_idsArray<integer>required

Array of Shopify variant IDs to update

inventory_policystringCONTINUEDENYrequired

The inventory policy to set for the variants

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

Response

200OKobject

Inventory policy update has been queued successfully

400Bad Requestobject

Bad request - missing or invalid parameters

401Unauthorized

Unauthorized

404Not Foundobject

Selling plan not found

422Unprocessable Entityobject

Invalid inventory policy

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Queue a bulk update of inventory policy for multiple variants
curl -X POST 'https://app.stoqapp.com/api/v1/external/preorders/{id}/bulk_toggle_inventory_policy' \
  -H 'Content-Type: application/json' \
  -d '{
    "shopify_variant_ids": [
      43900910010503,
      43900910010999
    ],
    "inventory_policy": "CONTINUE"
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/bulk_toggle_inventory_policy', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "shopify_variant_ids": [
        43900910010503,
        43900910010999
      ],
      "inventory_policy": "CONTINUE"
    }),
});

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

payload = {
  "shopify_variant_ids": [
    43900910010503,
    43900910010999
  ],
  "inventory_policy": "CONTINUE"
}

response = requests.post('https://app.stoqapp.com/api/v1/external/preorders/{id}/bulk_toggle_inventory_policy', json=payload)
data = response.json()
Request Body
{
  "shopify_variant_ids": [
    43900910010503,
    43900910010999
  ],
  "inventory_policy": "CONTINUE"
}
{
  "success": true,
  "message": "Inventory policy update queued",
  "variants_queued": [
    43900910010503,
    43900910010999
  ]
}
{
  "error": "string"
}
{
  "error": "string"
}
{
  "error": "string"
}

Update variant-specific settings for a selling plan

PATCH
https://app.stoqapp.com/api/v1/external/preorders/{id}/update_variant_settings

Update per-variant preorder settings within a selling plan, such as the variant's custom shipping_text and preorder_max_count (the cap on preorder units). Identify the variant with shopify_variant_id; only the settings you include are changed. Returns the updated variant settings.

Body

application/json
shopify_variant_idintegerrequired

Shopify variant ID to update settings for

shipping_textstring

Custom shipping text for this variant

preorder_max_countinteger

Maximum number of preorders allowed for this variant

Parameters

X-Auth-Tokenstringrequiredheader

API key for authentication

idstringrequiredpath

Selling plan ID

Response

200OKobject

Variant settings updated successfully

400Bad Requestobject

Bad request - missing required parameters or no settings to update

401Unauthorized

Unauthorized

404Not Foundobject

Selling plan or variant not found

422Unprocessable Entityobject

Failed to update variant settings

Authorization

ApiKeyAuthapiKey in header

Authenticate by sending your shop’s STOQ API key in the X-Auth-Token header. Find it in the STOQ app under Settings → Integrations → API Key — keep it secret. Every request also needs the shop context: Preorders endpoints resolve it from the API key; the one public endpoint, Back in Stock Create Intent, takes no key and identifies the shop via the X-Shopify-Shop-Domain header instead.

Update variant-specific settings for a selling plan
curl -X PATCH 'https://app.stoqapp.com/api/v1/external/preorders/{id}/update_variant_settings' \
  -H 'Content-Type: application/json' \
  -d '{
    "shopify_variant_id": 43900910010503,
    "shipping_text": "Ships July 2026",
    "preorder_max_count": 100
  }'
const response = await fetch('https://app.stoqapp.com/api/v1/external/preorders/{id}/update_variant_settings', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
      "shopify_variant_id": 43900910010503,
      "shipping_text": "Ships July 2026",
      "preorder_max_count": 100
    }),
});

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

payload = {
  "shopify_variant_id": 43900910010503,
  "shipping_text": "Ships July 2026",
  "preorder_max_count": 100
}

response = requests.patch('https://app.stoqapp.com/api/v1/external/preorders/{id}/update_variant_settings', json=payload)
data = response.json()
Request Body
{
  "shopify_variant_id": 43900910010503,
  "shipping_text": "Ships July 2026",
  "preorder_max_count": 100
}
{
  "success": true,
  "message": "Variant settings updated",
  "variant": {
    "shopify_variant_id": 43900910010503,
    "shipping_text": "Ships July 2026",
    "preorder_max_count": 100
  }
}
{
  "error": "string"
}
{
  "error": "string"
}
{
  "error": "string",
  "details": [
    "string"
  ]
}

Models

Intent

object
idstring

Unique identifier for the intent

blocked_atstring<date-time> | null

Timestamp when the intent was blocked from sending

channelstring

Communication channel used for notifications (e.g., Email, SMS)

emailstring

Customer's email address for notifications

notified_atstring<date-time> | null

Timestamp of the notification sent

optin_confirmedboolean

Whether the customer has confirmed their GDPR opt-in for notifications

phonestring

Customer's phone number for SMS notifications

quantityinteger

Requested quantity of the product when back in stock

sent_notifications_countinteger

Number of notifications sent for this intent

sourcestring
typestring

Type of the intent (e.g., restock, wishlist_reminder)

unsubscribed_atstring<date-time> | null

Timestamp when the customer unsubscribed from notifications

created_atstring<date-time>

Timestamp when the intent was created

updated_atstring<date-time>

Timestamp when the intent was last updated

customer_idstring

Unique identifier for the customer

intent_trigger_idstring | null

Identifier for the trigger that created this intent

product_variant_idstring | null

Internal product variant identifier

shop_idstring

Unique identifier for the shop

shopify_inventory_item_idinteger | null

Shopify's inventory item identifier

shopify_market_idinteger | null

Shopify's market identifier for multi-market stores

shopify_product_idinteger | null

Shopify's product identifier

shopify_variant_idinteger | null

Shopify's variant identifier

customer_namestring | null

Customer's full name

contactstring | null

Customer's contact information

customer_unsubscribed_atstring<date-time> | null

Timestamp when the customer unsubscribed from all notifications

accepts_marketingboolean | null

Whether the customer has opted in to receive marketing communications

notifications_countinteger | null

Total number of notifications sent for this intent

Example
{
  "id": "string",
  "blocked_at": "2024-01-15T09:30:00Z",
  "channel": "string",
  "email": "string",
  "notified_at": "2024-01-15T09:30:00Z",
  "optin_confirmed": true,
  "phone": "string",
  "quantity": 0,
  "sent_notifications_count": 0,
  "source": "string",
  "type": "string",
  "unsubscribed_at": "2024-01-15T09:30:00Z",
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "customer_id": "string",
  "intent_trigger_id": "string",
  "product_variant_id": "string",
  "shop_id": "string",
  "shopify_inventory_item_id": 0,
  "shopify_market_id": 0,
  "shopify_product_id": 0,
  "shopify_variant_id": 0,
  "customer_name": "string",
  "contact": "string",
  "customer_unsubscribed_at": "2024-01-15T09:30:00Z",
  "accepts_marketing": true,
  "notifications_count": 0
}

ProductVariantDemand

object

Product variant with demand metrics and product data

shopify_variant_idinteger

Shopify variant identifier

shopify_product_idinteger

Shopify product identifier

shopify_inventory_item_idinteger | null

Shopify inventory item identifier

totalinteger

Total number of intents (both pending and sent) for this variant

pendinginteger

Number of pending (unsent) intents for this variant

last_requested_atstring<date-time> | null

Timestamp of the most recent intent created for this variant

product_dataobject | null

Shopify product data including variants

Show child attributes
idinteger

Shopify product ID

titlestring

Product title

vendorstring

Product vendor/brand

variantsArray<object>

Array of product variants

Show child attributes
idinteger

Shopify variant ID

titlestring

Variant title (e.g., "Medium / Red")

skustring

Variant SKU

variant_dataobject | null

Specific variant data for this demand entry

Show child attributes
idinteger

Shopify variant ID

titlestring

Variant title (e.g., "Medium / Red")

skustring

Variant SKU

Example
{
  "shopify_variant_id": 0,
  "shopify_product_id": 0,
  "shopify_inventory_item_id": 0,
  "total": 0,
  "pending": 0,
  "last_requested_at": "2024-01-15T09:30:00Z",
  "product_data": {
    "id": 0,
    "title": "string",
    "vendor": "string",
    "variants": [
      {
        "id": 0,
        "title": "string",
        "sku": "string"
      }
    ]
  },
  "variant_data": {
    "id": 0,
    "title": "string",
    "sku": "string"
  }
}

SellingPlanInput

object

Input schema for creating or updating selling plans

namestring

Display name of the selling plan

internal_namestring

Internal name for the selling plan

enabledboolean

Whether the selling plan is enabled

billing_typestringexact_timeno_remaining_balancetime_after_checkout

Type of billing for the selling plan

billing_atstring<date-time>

Exact billing time if billing_type is exact_time

billing_after_n_intervalsinteger

Number of intervals after checkout to bill

billing_after_interval_typestringday

Type of interval for billing

billing_checkout_charge_amountnumber

Fixed amount to charge at checkout

billing_checkout_charge_percentagenumber

Percentage to charge at checkout

billing_checkout_charge_typestringpercentageprice

Type of checkout charge

billing_titlestring

Title for billing section

billing_descriptionstring

Description for billing section

delivery_typestringanchorasapexact_timeunknown

Type of delivery for the selling plan

delivery_atstring<date-time>

Exact delivery time if delivery_type is exact_time

delivery_after_n_intervalsinteger

Number of intervals after checkout for delivery

delivery_after_interval_typestringday

Type of interval for delivery

inventory_reserve_typestringon_saleon_fulfillment

When to reserve inventory

inventory_providerstringstoqshopify

Inventory provider

pricing_typestringpercentagepricefixed_amountno_discount

Type of pricing discount

pricing_amountnumber

Fixed discount amount

pricing_percentagenumber

Percentage discount

quantity_limit_textstring

Text to display for quantity limits

preorder_button_textstring

Text for the preorder button

preorder_button_text_colorstring

Text color for the preorder button

preorder_button_background_colorstring

Background color for the preorder button

preorder_button_colors_enabledboolean

Whether custom colors are enabled for the preorder button

preorder_discounted_price_enabledboolean

Whether to show discounted price on the preorder button

preorder_button_descriptionstring

Description text for the preorder button

preorder_button_description_background_colorstring

Background color for the preorder button description

preorder_button_description_border_radiusstring

Border radius for the preorder button description

preorder_button_description_quantity_limit_suffixstring

Suffix text for quantity limit in button description

preorder_button_description_shipping_text_prefixstring

Prefix text for shipping information in button description

preorder_button_description_show_quantity_limitboolean

Whether to show quantity limit in button description

preorder_button_description_show_shippingboolean

Whether to show shipping information in button description

preorder_button_description_text_colorstring

Text color for the preorder button description

preorder_badge_enabledboolean

Whether preorder badge is enabled

preorder_badge_textstring

Text for the preorder badge

preorder_badge_text_colorstring

Text color for the preorder badge

preorder_badge_background_colorstring

Background color for the preorder badge

preorder_shipping_textstring

Shipping text specific to preorders

shipping_textstring

Shipping information text

shipping_line_item_property_enabledboolean

Whether to enable shipping line item properties

shipping_applies_to_all_productsboolean

Whether shipping settings apply to all products

discount_textstring

Discount information text

preorder_tagsstring

Tags to apply to preorder items

product_variants_sourcestringallcollectioncustom

Source of product variants for this selling plan

product_variants_source_idinteger

ID of the source (e.g., collection ID)

markets_enabledboolean

Whether market-specific settings are enabled for this selling plan

shopify_market_idsArray<integer>

List of Shopify market IDs where this selling plan is available. Required if markets_enabled is true.

auto_collect_paymentboolean

Whether to automatically collect payment when the order is ready to fulfill

use_shopify_selling_planboolean

Whether to use Shopify's native selling plan functionality for this preorder offer. When true, this enables advanced selling plan features in Shopify.

enable_billing_widgetboolean

Whether to display the payment/billing widget on the product page

split_fulfillments_enabledboolean

Whether to enable split fulfillments for preorders. When enabled, preorder items can be shipped separately from regular items in the same order.

require_preorder_acknowledgementboolean

Whether customers must accept terms and conditions before adding a preorder item to their cart.

preorder_acknowledgement_textstring

The terms and conditions text that customers must acknowledge when require_preorder_acknowledgement is enabled.

allow_mixed_cartboolean

Whether to allow customers to mix preorder items with regular items in the same cart. When false, customers must purchase preorders separately.

mixed_cart_error_messagestring

Error message displayed to customers when they attempt to mix preorder and regular items in their cart (when allow_mixed_cart is false).

preorder_min_quantityinteger

Minimum quantity required per order for preorder items. When set, customers must purchase at least this many units.

preorder_max_quantityinteger

Maximum quantity allowed per order for preorder items. When set, customers cannot purchase more than this many units.

payment_line_item_property_enabledboolean

Whether to add payment information as a line item property (e.g., "Payment - Pay in full").

custom_line_item_property_textstring

Custom text to add as a line item property for preorder items. Useful for adding custom order notes or metadata.

auto_collect_payment_on_fulfillmentboolean

Whether to automatically collect remaining payment when the order is fulfilled (for partial payment preorders).

hold_fulfillments_enabledboolean

Whether to automatically hold fulfillments for preorder items. When enabled, fulfillments will be held until manually released.

hold_fulfillments_reason_notestring

The reason note displayed when fulfillments are held (when hold_fulfillments_enabled is true).

disable_button_until_acknowledgedboolean

Whether to disable the add to cart button until the customer acknowledges the preorder terms (when require_preorder_acknowledgement is true).

Example
{
  "name": "string",
  "internal_name": "string",
  "enabled": true,
  "billing_type": "exact_time",
  "billing_at": "2024-01-15T09:30:00Z",
  "billing_after_n_intervals": 0,
  "billing_after_interval_type": "day",
  "billing_checkout_charge_amount": 0,
  "billing_checkout_charge_percentage": 0,
  "billing_checkout_charge_type": "percentage",
  "billing_title": "string",
  "billing_description": "string",
  "delivery_type": "anchor",
  "delivery_at": "2024-01-15T09:30:00Z",
  "delivery_after_n_intervals": 0,
  "delivery_after_interval_type": "day",
  "inventory_reserve_type": "on_sale",
  "inventory_provider": "stoq",
  "pricing_type": "percentage",
  "pricing_amount": 0,
  "pricing_percentage": 0,
  "quantity_limit_text": "string",
  "preorder_button_text": "string",
  "preorder_button_text_color": "string",
  "preorder_button_background_color": "string",
  "preorder_button_colors_enabled": true,
  "preorder_discounted_price_enabled": true,
  "preorder_button_description": "string",
  "preorder_button_description_background_color": "string",
  "preorder_button_description_border_radius": "string",
  "preorder_button_description_quantity_limit_suffix": "string",
  "preorder_button_description_shipping_text_prefix": "string",
  "preorder_button_description_show_quantity_limit": true,
  "preorder_button_description_show_shipping": true,
  "preorder_button_description_text_color": "string",
  "preorder_badge_enabled": true,
  "preorder_badge_text": "string",
  "preorder_badge_text_color": "string",
  "preorder_badge_background_color": "string",
  "preorder_shipping_text": "string",
  "shipping_text": "string",
  "shipping_line_item_property_enabled": true,
  "shipping_applies_to_all_products": true,
  "discount_text": "string",
  "preorder_tags": "string",
  "product_variants_source": "all",
  "product_variants_source_id": 0,
  "markets_enabled": true,
  "shopify_market_ids": [
    0
  ],
  "auto_collect_payment": true,
  "use_shopify_selling_plan": true,
  "enable_billing_widget": true,
  "split_fulfillments_enabled": true,
  "require_preorder_acknowledgement": true,
  "preorder_acknowledgement_text": "string",
  "allow_mixed_cart": true,
  "mixed_cart_error_message": "string",
  "preorder_min_quantity": 0,
  "preorder_max_quantity": 0,
  "payment_line_item_property_enabled": true,
  "custom_line_item_property_text": "string",
  "auto_collect_payment_on_fulfillment": true,
  "hold_fulfillments_enabled": true,
  "hold_fulfillments_reason_note": "string",
  "disable_button_until_acknowledged": true
}

SellingPlan

object
idstring

Unique identifier for the selling plan

namestring

Display name of the selling plan

internal_namestring

Internal name for the selling plan

enabledboolean

Whether the selling plan is enabled

billing_typestringexact_timeno_remaining_balancetime_after_checkout

Type of billing for the selling plan

billing_atstring<date-time> | null

Exact billing time if billing_type is exact_time

billing_after_n_intervalsinteger | null

Number of intervals after checkout to bill

billing_after_interval_typestringday

Type of interval for billing

billing_checkout_charge_amountnumber | null

Fixed amount to charge at checkout

billing_checkout_charge_percentagenumber | null

Percentage to charge at checkout

billing_checkout_charge_typestringpercentageprice

Type of checkout charge

billing_titlestring

Title for billing section

billing_descriptionstring

Description for billing section

delivery_typestringanchorasapexact_timeunknown

Type of delivery for the selling plan

delivery_atstring<date-time> | null

Exact delivery time if delivery_type is exact_time

delivery_after_n_intervalsinteger | null

Number of intervals after checkout for delivery

delivery_after_interval_typestringday

Type of interval for delivery

inventory_reserve_typestringon_saleon_fulfillment

When to reserve inventory

inventory_providerstringstoqshopify

Inventory provider

pricing_typestringpercentagepricefixed_amountno_discount

Type of pricing discount

pricing_amountnumber | null

Fixed discount amount

pricing_percentagenumber | null

Percentage discount

quantity_limit_textstring

Text to display for quantity limits

preorder_button_textstring

Text for the preorder button

preorder_button_text_colorstring

Text color for the preorder button

preorder_button_background_colorstring

Background color for the preorder button

preorder_button_colors_enabledboolean

Whether custom colors are enabled for the preorder button

preorder_discounted_price_enabledboolean

Whether to show discounted price on the preorder button

preorder_button_descriptionstring

Description text for the preorder button

preorder_button_description_background_colorstring

Background color for the preorder button description

preorder_button_description_border_radiusstring

Border radius for the preorder button description

preorder_button_description_quantity_limit_suffixstring

Suffix text for quantity limit in button description

preorder_button_description_shipping_text_prefixstring

Prefix text for shipping information in button description

preorder_button_description_show_quantity_limitboolean

Whether to show quantity limit in button description

preorder_button_description_show_shippingboolean

Whether to show shipping information in button description

preorder_button_description_text_colorstring

Text color for the preorder button description

preorder_badge_enabledboolean

Whether preorder badge is enabled

preorder_badge_textstring

Text for the preorder badge

preorder_badge_text_colorstring

Text color for the preorder badge

preorder_badge_background_colorstring

Background color for the preorder badge

preorder_shipping_textstring

Shipping text specific to preorders

shipping_textstring

Shipping information text

shipping_line_item_property_enabledboolean

Whether to enable shipping line item properties

shipping_applies_to_all_productsboolean

Whether shipping settings apply to all products

discount_textstring

Discount information text

preorder_tagsstring

Tags to apply to preorder items

product_variants_sourcestringallcollectioncustom

Source of product variants for this selling plan

product_variants_source_idinteger | null

ID of the source (e.g., collection ID)

selling_plan_product_variants_countinteger

Number of product variants associated with this selling plan

shopify_selling_plan_idinteger | null

Shopify selling plan ID

shopify_selling_plan_group_idinteger | null

Shopify selling plan group ID

use_shopify_selling_planboolean

Whether to use Shopify's native selling plan functionality for this preorder offer. When true, this enables advanced selling plan features in Shopify.

enable_billing_widgetboolean

Whether to display the payment/billing widget on the product page

split_fulfillments_enabledboolean

Whether to enable split fulfillments for preorders. When enabled, preorders will be separted into its own fulfillment order.

require_preorder_acknowledgementboolean

Whether customers must accept terms and conditions before adding a preorder item to their cart.

preorder_acknowledgement_textstring

The terms and conditions text that customers must acknowledge when require_preorder_acknowledgement is enabled.

allow_mixed_cartboolean

Whether to allow customers to mix preorder items with regular items in the same cart. When false, customers must purchase preorders separately.

mixed_cart_error_messagestring

Error message displayed to customers when they attempt to mix preorder and regular items in their cart (when allow_mixed_cart is false).

preorder_min_quantityinteger | null

Minimum quantity required per order for preorder items. When set, customers must purchase at least this many units.

preorder_max_quantityinteger | null

Maximum quantity allowed per order for preorder items. When set, customers cannot purchase more than this many units.

payment_line_item_property_enabledboolean

Whether to add payment information as a line item property (e.g., "Payment - Pay in full").

custom_line_item_property_textstring | null

Custom text to add as a line item property for preorder items. Useful for adding custom order notes or metadata.

auto_collect_payment_on_fulfillmentboolean

Whether to automatically collect remaining payment when the order is fulfilled (for partial payment preorders).

hold_fulfillments_enabledboolean

Whether to automatically hold fulfillments for preorder items. When enabled, fulfillments will be held until manually released.

hold_fulfillments_reason_notestring

The reason note displayed when fulfillments are held (when hold_fulfillments_enabled is true).

disable_button_until_acknowledgedboolean

Whether to disable the add to cart button until the customer acknowledges the preorder terms (when require_preorder_acknowledgement is true).

shop_idinteger

Shop ID this selling plan belongs to

market_idinteger | null

Market ID for multi-market stores

created_atstring<date-time>

Timestamp when the selling plan was created

updated_atstring<date-time>

Timestamp when the selling plan was last updated

discarded_atstring<date-time> | null

Timestamp when the selling plan was soft deleted

ongoing_jobboolean

Whether there is an ongoing job for this selling plan

shopify_variant_idsArray<integer>

List of Shopify variant IDs associated with this selling plan

Example
{
  "id": "string",
  "name": "string",
  "internal_name": "string",
  "enabled": true,
  "billing_type": "exact_time",
  "billing_at": "2024-01-15T09:30:00Z",
  "billing_after_n_intervals": 0,
  "billing_after_interval_type": "day",
  "billing_checkout_charge_amount": 0,
  "billing_checkout_charge_percentage": 0,
  "billing_checkout_charge_type": "percentage",
  "billing_title": "string",
  "billing_description": "string",
  "delivery_type": "anchor",
  "delivery_at": "2024-01-15T09:30:00Z",
  "delivery_after_n_intervals": 0,
  "delivery_after_interval_type": "day",
  "inventory_reserve_type": "on_sale",
  "inventory_provider": "stoq",
  "pricing_type": "percentage",
  "pricing_amount": 0,
  "pricing_percentage": 0,
  "quantity_limit_text": "string",
  "preorder_button_text": "string",
  "preorder_button_text_color": "string",
  "preorder_button_background_color": "string",
  "preorder_button_colors_enabled": true,
  "preorder_discounted_price_enabled": true,
  "preorder_button_description": "string",
  "preorder_button_description_background_color": "string",
  "preorder_button_description_border_radius": "string",
  "preorder_button_description_quantity_limit_suffix": "string",
  "preorder_button_description_shipping_text_prefix": "string",
  "preorder_button_description_show_quantity_limit": true,
  "preorder_button_description_show_shipping": true,
  "preorder_button_description_text_color": "string",
  "preorder_badge_enabled": true,
  "preorder_badge_text": "string",
  "preorder_badge_text_color": "string",
  "preorder_badge_background_color": "string",
  "preorder_shipping_text": "string",
  "shipping_text": "string",
  "shipping_line_item_property_enabled": true,
  "shipping_applies_to_all_products": true,
  "discount_text": "string",
  "preorder_tags": "string",
  "product_variants_source": "all",
  "product_variants_source_id": 0,
  "selling_plan_product_variants_count": 0,
  "shopify_selling_plan_id": 0,
  "shopify_selling_plan_group_id": 0,
  "use_shopify_selling_plan": true,
  "enable_billing_widget": true,
  "split_fulfillments_enabled": true,
  "require_preorder_acknowledgement": true,
  "preorder_acknowledgement_text": "string",
  "allow_mixed_cart": true,
  "mixed_cart_error_message": "string",
  "preorder_min_quantity": 0,
  "preorder_max_quantity": 0,
  "payment_line_item_property_enabled": true,
  "custom_line_item_property_text": "string",
  "auto_collect_payment_on_fulfillment": true,
  "hold_fulfillments_enabled": true,
  "hold_fulfillments_reason_note": "string",
  "disable_button_until_acknowledged": true,
  "shop_id": 0,
  "market_id": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "discarded_at": "2024-01-15T09:30:00Z",
  "ongoing_job": true,
  "shopify_variant_ids": [
    0
  ]
}

SellingPlanProductVariantsResponse

object
selling_plan_idstring

ID of the selling plan

selling_plan_namestring

Name of the selling plan

currencystring

Shop currency code

product_variantsArray<ProductVariantDetails>

List of product variants associated with this selling plan

Show child attributes
shopify_product_idinteger

Shopify product ID

shopify_variant_idinteger

Shopify variant ID

product_titlestring

Product title

variant_titlestring

Variant title (null for single-variant products)

preorder_units_soldinteger

Total units sold through preorders for this variant

preorder_max_countinteger | null

Maximum number of preorders allowed for this variant

shipping_textstring | null

Custom shipping text configured for this variant in the selling plan

metaobject
Show child attributes
total_variantsinteger

Total number of variants in results

total_units_soldinteger

Total units sold across all variants

Example
{
  "selling_plan_id": "string",
  "selling_plan_name": "string",
  "currency": "string",
  "product_variants": [
    {
      "shopify_product_id": 0,
      "shopify_variant_id": 0,
      "product_title": "string",
      "variant_title": "string",
      "preorder_units_sold": 0,
      "preorder_max_count": 0,
      "shipping_text": "string"
    }
  ],
  "meta": {
    "total_variants": 0,
    "total_units_sold": 0
  }
}

ProductVariantDetails

object
shopify_product_idinteger

Shopify product ID

shopify_variant_idinteger

Shopify variant ID

product_titlestring

Product title

variant_titlestring

Variant title (null for single-variant products)

preorder_units_soldinteger

Total units sold through preorders for this variant

preorder_max_countinteger | null

Maximum number of preorders allowed for this variant

shipping_textstring | null

Custom shipping text configured for this variant in the selling plan

Example
{
  "shopify_product_id": 0,
  "shopify_variant_id": 0,
  "product_title": "string",
  "variant_title": "string",
  "preorder_units_sold": 0,
  "preorder_max_count": 0,
  "shipping_text": "string"
}

SellingPlanSingleVariantResponse

object
selling_plan_idstring

ID of the selling plan

selling_plan_namestring

Name of the selling plan

currencystring

Shop currency code

product_variantProductVariantDetails
Show child attributes
shopify_product_idinteger

Shopify product ID

shopify_variant_idinteger

Shopify variant ID

product_titlestring

Product title

variant_titlestring

Variant title (null for single-variant products)

preorder_units_soldinteger

Total units sold through preorders for this variant

preorder_max_countinteger | null

Maximum number of preorders allowed for this variant

shipping_textstring | null

Custom shipping text configured for this variant in the selling plan

metaobject
Show child attributes
total_units_soldinteger

Units sold for this variant

Example
{
  "selling_plan_id": "string",
  "selling_plan_name": "string",
  "currency": "string",
  "product_variant": {
    "shopify_product_id": 0,
    "shopify_variant_id": 0,
    "product_title": "string",
    "variant_title": "string",
    "preorder_units_sold": 0,
    "preorder_max_count": 0,
    "shipping_text": "string"
  },
  "meta": {
    "total_units_sold": 0
  }
}

SellingPlanList

object

Simplified selling plan object for list views

idstring

Unique identifier for the selling plan

namestring

Display name of the selling plan

internal_namestring

Internal name for the selling plan

enabledboolean

Whether the selling plan is enabled

selling_plan_product_variants_countinteger

Number of product variants associated with this selling plan

created_atstring<date-time>

Timestamp when the selling plan was created

updated_atstring<date-time>

Timestamp when the selling plan was last updated

shopify_variant_idsArray<integer>

List of Shopify variant IDs associated with this selling plan

Example
{
  "id": "string",
  "name": "string",
  "internal_name": "string",
  "enabled": true,
  "selling_plan_product_variants_count": 0,
  "created_at": "2024-01-15T09:30:00Z",
  "updated_at": "2024-01-15T09:30:00Z",
  "shopify_variant_ids": [
    0
  ]
}