Detect Demand Anomalies
POST/api/inventory-forecasting/anomalies/detect
Detect one-off demand anomalies (spikes, drops, and stockout gaps) in the daily sales history of one or more products. Runs synchronously, persists each flagged point, and returns them.
Authentication: Requires Bearer token.
The detector scores each day with a robust modified z-score built from the median and median absolute deviation, so a handful of extreme days cannot mask the rest. The k threshold is expressed in robust standard deviations; lower values flag more points. Each day is classified as:
- spike_up: demand far above the local norm (often a promotion).
- drop_down: demand far below the local norm.
- stockout_zero: a zero-sales gap consistent with being out of stock.
Detected points feed two workflows:
- Resolve them (see Resolve / Bulk Resolve Demand Anomalies) as excluded, smoothed, or kept_tagged. Points resolved as excluded or smoothed are the ones a build with exclude_detected_anomalies true removes or replaces before computing the baseline, de-contaminating the velocity.
- Cluster spike_up points into candidate promotions via Suggest Promo Windows. A spike can also be linked to a promo_window_id when resolved as kept_tagged.
Body fields:
- product_ids (required): array of product IDs, at least one.
- k (optional): sensitivity threshold in robust standard deviations, 0.1-20 (default 3.0). Lower flags more points.
- start_date / end_date (optional, YYYY-MM-DD): detection window. Defaults to the trailing 365 days.
- sales_filters (optional): object narrowing which sales feed the series.
- warehouse_id (optional): restrict the series to one warehouse.
Each flagged point has a direction of spike_up, drop_down, or stockout_zero and a status of detected until it is resolved.
Request
Responses
- 200
- 401
- 403
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Validation failed — the body is a field → messages map (Laravel shape) or the platform envelope with a stable machine-readable code. Fix the payload and resubmit.
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.