Skip to content

Reports

Back-in-stock analytics — the same numbers as the Back in Stock Overview and Reports pages, as JSON.

BetaAPI v2 is in public beta: endpoints, fields and behaviour can change before general availability. See the changelog

Last updated

The back-in-stock reports resource returns the numbers the merchant sees on the Back in Stock Overview and the Reports > Back in stock pages, like the preorder reports. Each report is a JSON read; reads run against read replicas. There is no CSV export in the API.

Path prefix: /back_in_stock/reports, under the base URL https://app.stoqapp.com/api/v2/external.

GET /back_in_stock/reports

Open in the API reference

Returns the catalog of available reports — { "reports": [{ "name", "description", "aliases", "url" }] } — generated from the live registry so it can’t drift from the actual report actions.

Param Type Notes
from, to ISO 8601 date or timestamp Window — defaults to the last 30 days. A bare date is that whole day in the shop’s time zone
range all_time The dashboard’s All time, instead of from/to

Each report takes only the filters its dashboard view has; they are listed with the report. Shopify ids in requests and responses are shopify_*_id, a gid string in responses. Every response echoes the resolved window at the top: "window": { "from": "...", "to": "..." }, or null for range=all_time.

Every report calls the same service as the dashboard view it names, so the numbers match the dashboard. summary is summed from the shop’s daily totals, as the Overview tiles are (all time reads the lifetime totals, as the Home card does). The charts (signups, notifications, conversions) count live, as the Overview charts do: the bucket size is daily up to 60 days, weekly up to 180 days, then monthly (interval in the response), and buckets are UTC days, weeks and months, as on the charts. date is the bucket’s first day.

Method Path Dashboard view
GET /back_in_stock/reports/summary Overview tiles
GET /back_in_stock/reports/signups Overview signups chart
GET /back_in_stock/reports/notifications Overview notifications chart
GET /back_in_stock/reports/conversions Overview orders chart
GET /back_in_stock/reports/products_in_demand Reports > Products in demand table
GET /back_in_stock/reports/product_revenue Reports > Revenue table
GET /back_in_stock/reports/wait_duration The wait-time chart: median, longest, histogram
GET /back_in_stock/reports/engagement Reports > Engagement

The Back in stock Overview tiles, and the same totals as the Home analytics card. Shop-wide only: send from/to or range=all_time. A window is summed from the shop’s daily totals; range=all_time reads revenue, orders, signups, emails_sent and sms_sent from the shop’s lifetime totals, as Home’s All time does. For people still waiting use products_in_demand.

{
"window": { "from": "...", "to": "..." },
"currency": "USD",
"totals": {
"revenue": "4812.50",
"orders": 96,
"average_order_value": "50.13",
"unique_customers": 81,
"signups": 420,
"notifications_sent": 461,
"emails_sent": 410,
"sms_sent": 51
}
}
  • revenue, orders: orders attributed to an alert at medium or high confidence, and their value.
  • unique_customers: the dashboard’s buyers tile, summed over the days.
  • signups: every signup created; a shopper signed up by email and SMS counts twice, as on the tile.
  • sms_sent: every back-in-stock SMS sent, delivered or not, the count plan usage bills.

The Overview signups chart: signups created per bucket.

{
"window": { "...": "..." },
"interval": "daily",
"series": [
{ "date": "2026-06-01", "signups": 24 }
]
}

The Overview notifications chart: emails and delivered SMS sent per bucket, and the orders attributed to alerts.

{
"window": { "...": "..." },
"interval": "daily",
"series": [
{ "date": "2026-06-01", "notifications_sent": 115, "emails_sent": 101, "sms_sent": 14, "orders": 3 }
]
}

notifications_sent is emails_sent plus sms_sent.

The Overview orders chart: orders attributed to an alert at medium or high confidence, and their revenue.

{
"window": { "...": "..." },
"interval": "daily",
"currency": "USD",
"series": [
{ "date": "2026-06-01", "orders": 8, "revenue": "401.00" }
]
}

The Products in demand table: variants (or products) ranked by demand — the answer to “what should I restock first?”. total is signups created in the window. pending is how many of them have not been notified yet. A row appears when it has a signup in the window; send range=all_time for everyone waiting now. Deleted variants are left out when the shop has the dashboard set to hide them.

Param Notes
group_by variant (default) / product
sort_by pending (default) / total / last_requested_at
direction desc (default) / asc
count_by customers / signups; omitted, the dashboard default. The response echoes it
search Product title or SKU, as the dashboard search box
vendors Comma-separated vendor names
tags Comma-separated product tags, as the dashboard’s Tag filter
shopify_market_ids Comma-separated, each numeric or gid://shopify/Market/…, as the dashboard’s market filter
include_inventory true adds inventory_available to variant rows, the table’s Inventory column. Asks Shopify once per page
include_prices true adds price and compare_at_price to variant rows, the table’s Price and Compare at columns. Asks Shopify once per page
page, per_page per_page default 25, max 500
{
"window": { "...": "..." },
"group_by": "variant",
"sort_by": "pending",
"direction": "desc",
"count_by": "customers",
"rows": [
{
"shopify_variant_id": "gid://shopify/ProductVariant/123",
"shopify_product_id": "gid://shopify/Product/456",
"variant_title": "Small / Blue",
"product_title": "Classic Tee",
"sku": "TEE-S-BLU",
"image_url": "https://cdn.shopify.com/s/files/tee-blue.jpg",
"deleted": false,
"variants_count": 6,
"inventory_available": 0,
"price": "25.00",
"compare_at_price": "30.00",
"pending": 42,
"total": 65,
"last_requested_at": "2026-06-09T08:30:00Z"
}
],
"meta": { "total_count": 1, "page": 1, "per_page": 25, "total_pages": 1 }
}

With group_by=product, rows have shopify_product_id, product_title, image_url and variants_count, and no variant fields; include_inventory and include_prices add nothing to them. deleted is the dashboard’s “(Deleted)” label: on a product row, every variant of the product is deleted. image_url is the variant’s image, else the product’s.

inventory_available is the stock available in the locations the shop’s market or location filter allows, summed, as the Inventory column shows it; it is null when Shopify has no level for the variant. price and compare_at_price are strings in the shop’s currency, null when Shopify has none. last_requested_at is the latest signup in the window.

With count_by=signups, every signup counts, so a shopper signed up for one variant by email and SMS counts twice. With count_by=customers, a signup is one person waiting on one variant: the same shopper signing up for the same variant by email and by SMS counts once, and the same shopper signing up for two sizes counts twice.

Param Notes
shopify_variant_id, shopify_product_id gid or numeric; one variant or product, as the dashboard’s wait-time chart
shopify_market_ids Comma-separated, each numeric or gid://shopify/Market/…, as the waitlist page’s Markets filter

Returns median_wait_days, max_wait_days, interval and distribution (paid plans only; distribution_included_in_plan says which). For how many are waiting, use products_in_demand.

Terminal window
curl 'https://app.stoqapp.com/api/v2/external/back_in_stock/reports/signups?from=2026-03-01&to=2026-06-01' \
-H "X-Auth-Token: $STOQ_API_KEY"

The 92-day window returns weekly buckets, as the dashboard chart does.

Was this page helpful?

Still stuck? Ask Quinn or chat with support