PUT/v1/tenants/{tenantId}/demand_planning/sales_forecast_batches/{batchId}

Upload a batch of sales forecasts Experimental

The batch id is generated by the client. Retrying the same id with the same payload is safe and returns 200 with the existing status; the same id with a different payload is a 409. The body may be gzip-compressed (Content-Encoding: gzip). Format errors are reported as a 400 that lists every problem with its path in the document; nothing is stored in that case. Whether stores and SKUs exist is checked when the batch is processed and reported per item in the batch status. Limits are published at GET /limits. A corrected batch is a new run: new batch id, newer generatedAt, and its own batchIndex/batchTotal (or none). Send batches sequentially; the per-client rate limit makes parallel uploads no faster.

Parameters

tenantIdrequired
batchIdrequired

Client-generated UUID for this batch

Content-Encodingoptional

gzip when the body is compressed

Request body (required)

application/json

A batch of sales forecasts from one planning run

batchIndexoptional

1-based position of this batch within the run. Set together with batchTotal or not at all.

  • Format: int32
Example12
batchTotaloptional

Number of batches in the run

  • Format: int32
Example140
extoptional

Partner-owned fields. Never interpreted by Snowbee.

Show dictionary values

Each dictionary key maps to .

generatedAtrequired

Timestamp of the planning run that produced every item in the batch. Identical for all batches of one run; a later run must have a later value.

  • Format: ISO 8681 timestamp
Example"2026-08-28T03:12:00Z"
itemCountrequired

Must equal the length of items

  • Format: int32
Example5000
itemsrequired
Show item fields

Sales forecast for one store and SKU. The item replaces the whole forecast held for that store and SKU.

ecomStoreNumberoptional

Ecom store number. Exactly one of retailStoreNumber and ecomStoreNumber must be set.

Example"9001"
extoptional

Partner-owned fields. Never interpreted by Snowbee.

Show dictionary values

Each dictionary key maps to .

horizonEndDaterequired

Last forecast day, an ISO 8601 calendar date. Must equal horizonStartDate plus quantities.length - 1 days; catches horizons of the wrong length.

  • Format: date
Example"2026-09-30"
horizonStartDaterequired

First forecast day, an ISO 8601 calendar date. No earlier than 7 days ago.

  • Format: date
Example"2026-09-01"
quantitiesrequired

Expected gross sales quantity per day from horizonStartDate to horizonEndDate inclusive, as decimal strings with at most 4 decimals. quantities[i] is the forecast for horizonStartDate plus i days.

Example["4.7","3.1","0","5.25"]
retailStoreNumberoptional

Retail store number. Exactly one of retailStoreNumber and ecomStoreNumber must be set.

Example"1001"
skuNumberrequired
Example"10025"

Responses

200Response

Same batch already stored

application/json
batchIdrequired

Client-generated batch id

Example"0192a3b4-5c6d-7e8f-9012-3456789abcde"
batchIndexoptional
  • Format: int32
Example12
batchKindrequired
Allowed values"SALES_FORECAST""REPLENISHMENT_PARAMETERS"
batchTotaloptional
  • Format: int32
Example140
completedTimeoptional
  • Format: ISO 8681 timestamp
Example"2025-10-28T12:37:42Z"
countsoptional

Null until the batch has been processed

Show child fields
apiUpdatesDisabledrequired

Items skipped because the retail store is not set to take updates from the API in Snowbee (replenishment parameters only)

  • Format: int32
Example0
appliedrequired

Items written to Snowbee

  • Format: int32
Example4996
itemsrequired
  • Format: int32
Example5000
lockedrequired

Items skipped because the line is locked in Snowbee (replenishment parameters only)

  • Format: int32
Example0
rejectedrequired

Items not applied; listed in rejectedItems

  • Format: int32
Example4
supersededrequired

Items skipped because a newer generatedAt was already applied for the same key

  • Format: int32
Example0
unchangedrequired

Items skipped because they match the values the store already uses (replenishment parameters only)

  • Format: int32
Example0
errorMessageoptional

Why the batch FAILED

generatedAtrequired
  • Format: ISO 8681 timestamp
Example"2026-08-28T03:12:00Z"
itemCountrequired
  • Format: int32
Example5000
progressrequired
Allowed values"PENDING""PROCESSING""COMPLETED""COMPLETED_WITH_REJECTED_ITEMS""FAILED"
receivedTimerequired

When Snowbee stored the batch

  • Format: ISO 8681 timestamp
Example"2026-08-28T03:12:04.120Z"
rejectedItemsoptional

First rejected items; null until processed. See rejectedItemsTruncated.

Show item fields
coderequired

One of: UNKNOWN_RETAIL_STORE, RETAIL_STORE_NOT_RELEASED, UNKNOWN_ECOM_STORE, ECOM_STORE_NOT_RELEASED, UNKNOWN_SKU, SKU_NOT_IN_ASSORTMENT, REPLENISHMENT_TYPE_MANUAL

Example"UNKNOWN_SKU"
ecomStoreNumberoptional
Example"9001"
indexrequired

0-based index into items

  • Format: int32
Example17
messageoptional
retailStoreNumberoptional
Example"1001"
skuNumberoptional
Example"10025"
rejectedItemsTruncatedrequired

True when more items were rejected than are listed

Examplefalse
startedTimeoptional
  • Format: ISO 8681 timestamp
Example"2025-10-28T12:37:42Z"
warningsoptional

Warnings recorded at receipt and during processing

Show item fields

A non-fatal observation about the batch

coderequired

UNKNOWN_FIELD: a field Snowbee does not know and did not apply

Example"UNKNOWN_FIELD"
countoptional

How many times the observation occurred

  • Format: int32
Example5000
fieldoptional

Path of the field, with [] for array elements

Example"items[].campaignQuantity"
messageoptional
202Response

New batch stored

application/json
batchIdrequired

Client-generated batch id

Example"0192a3b4-5c6d-7e8f-9012-3456789abcde"
batchIndexoptional
  • Format: int32
Example12
batchKindrequired
Allowed values"SALES_FORECAST""REPLENISHMENT_PARAMETERS"
batchTotaloptional
  • Format: int32
Example140
completedTimeoptional
  • Format: ISO 8681 timestamp
Example"2025-10-28T12:37:42Z"
countsoptional

Null until the batch has been processed

Show child fields
apiUpdatesDisabledrequired

Items skipped because the retail store is not set to take updates from the API in Snowbee (replenishment parameters only)

  • Format: int32
Example0
appliedrequired

Items written to Snowbee

  • Format: int32
Example4996
itemsrequired
  • Format: int32
Example5000
lockedrequired

Items skipped because the line is locked in Snowbee (replenishment parameters only)

  • Format: int32
Example0
rejectedrequired

Items not applied; listed in rejectedItems

  • Format: int32
Example4
supersededrequired

Items skipped because a newer generatedAt was already applied for the same key

  • Format: int32
Example0
unchangedrequired

Items skipped because they match the values the store already uses (replenishment parameters only)

  • Format: int32
Example0
errorMessageoptional

Why the batch FAILED

generatedAtrequired
  • Format: ISO 8681 timestamp
Example"2026-08-28T03:12:00Z"
itemCountrequired
  • Format: int32
Example5000
progressrequired
Allowed values"PENDING""PROCESSING""COMPLETED""COMPLETED_WITH_REJECTED_ITEMS""FAILED"
receivedTimerequired

When Snowbee stored the batch

  • Format: ISO 8681 timestamp
Example"2026-08-28T03:12:04.120Z"
rejectedItemsoptional

First rejected items; null until processed. See rejectedItemsTruncated.

Show item fields
coderequired

One of: UNKNOWN_RETAIL_STORE, RETAIL_STORE_NOT_RELEASED, UNKNOWN_ECOM_STORE, ECOM_STORE_NOT_RELEASED, UNKNOWN_SKU, SKU_NOT_IN_ASSORTMENT, REPLENISHMENT_TYPE_MANUAL

Example"UNKNOWN_SKU"
ecomStoreNumberoptional
Example"9001"
indexrequired

0-based index into items

  • Format: int32
Example17
messageoptional
retailStoreNumberoptional
Example"1001"
skuNumberoptional
Example"10025"
rejectedItemsTruncatedrequired

True when more items were rejected than are listed

Examplefalse
startedTimeoptional
  • Format: ISO 8681 timestamp
Example"2025-10-28T12:37:42Z"
warningsoptional

Warnings recorded at receipt and during processing

Show item fields

A non-fatal observation about the batch

coderequired

UNKNOWN_FIELD: a field Snowbee does not know and did not apply

Example"UNKNOWN_FIELD"
countoptional

How many times the observation occurred

  • Format: int32
Example5000
fieldoptional

Path of the field, with [] for array elements

Example"items[].campaignQuantity"
messageoptional
400Validation failed; details is a SbPublicApiValidationErrorDetails

Validation failed; details is a SbPublicApiValidationErrorDetails

application/json
detailsoptional

Structured details; shape depends on error

errorrequired
Example"VALIDATION_ERROR"
messagerequired

Human-readable error message

Example"3 of 5000 items failed validation"
resolutionrequired

Suggested next action

Example"Correct the invalid items and retry the complete batch"
401Response
application/json
errorrequired

Stable error code

Example"INVALID_REQUEST"
messagerequired

Human-readable error message

Example"Invalid customer ID format"
resolutionrequired

Suggested next action

Example"Correct the customer ID and retry the request"
403Response
application/json
errorrequired

Stable error code

Example"INVALID_REQUEST"
messagerequired

Human-readable error message

Example"Invalid customer ID format"
resolutionrequired

Suggested next action

Example"Correct the customer ID and retry the request"
409Batch id already used with a different payload

Batch id already used with a different payload

application/json
errorrequired

Stable error code

Example"INVALID_REQUEST"
messagerequired

Human-readable error message

Example"Invalid customer ID format"
resolutionrequired

Suggested next action

Example"Correct the customer ID and retry the request"
413A limit was exceeded; details is a SbPublicApiLimitExceededDetails

A limit was exceeded; details is a SbPublicApiLimitExceededDetails

application/json
detailsoptional

Structured details; shape depends on error

errorrequired
Example"VALIDATION_ERROR"
messagerequired

Human-readable error message

Example"3 of 5000 items failed validation"
resolutionrequired

Suggested next action

Example"Correct the invalid items and retry the complete batch"
415Content-Type must be application/json

Content-Type must be application/json

application/json
errorrequired

Stable error code

Example"INVALID_REQUEST"
messagerequired

Human-readable error message

Example"Invalid customer ID format"
resolutionrequired

Suggested next action

Example"Correct the customer ID and retry the request"