Skip to main content

The API

The Stock Count API is what the Hii Retail Inventory app uses, and it is available to integrations on the same terms — for planning counts centrally, counting from another client, or reading results.

https://stock-count-api.retailsvc.com/api/v1

Every request needs a Hii Retail access token and is made for one tenant. The permission each endpoint requires is listed in the OpenAPI document. Creating, editing, deleting and submitting a count are permitted per count type — a user can be allowed to run cycle counts without being allowed to submit a full count — which is why those endpoints take the count's type as a query parameter.

Every write is asynchronous​

🛑 Every endpoint that changes something returns 202 Accepted once the request is valid, and the change is applied a moment later. That covers creating, editing and deleting counts, registering and deleting lines, marking a category as done, submitting, importing, and every recurring-definition write.

  • A count read back immediately after it was created can return 404. Retry after a short delay, or poll.
  • A newly created count holds no items until its list has been prepared: itemsGeneratedDateTime is null until then. See How a count works.
  • A 202 means the request was accepted, not that it was applied. The API rejects a line for a count that is already completed or deleted, but a line sent in the same moment as the submission can be accepted and still miss the count: once a count is submitted, its published result does not change. Finish counting before submitting.

Retrying safely​

This is about your retries — a client resending a request because it timed out or got no answer. Stock Count's own processing needs no care from you: the API gives each request its identifiers before passing it on, so a request that is delivered twice inside the service is recognised and applied once.

A retry from the client, though, is a new request, and the API cannot tell it from a second, different one — unless it carries your identifier:

RequestIdentifier to supplyA client retry without it
Create a countstockCountId in the bodycreates a second count
Register a linelineId in the body⚠ creates a second line, and the item's counted quantity doubles — see below
Create a recurring definitionrecurringStockCountId in the bodycreates a second definition

Why a line can double although countedQuantity is a total. countedQuantity is the total for that line: sending the same lineId again replaces the line's quantity, it never adds to it. An item's counted quantity, on the other hand, is the sum of all its lines — deliberately, because that is how an item found in several places is counted: 10 on shelf A, 14 on shelf B and 20 in the back room are three lines, and the item's count is 44.

A line sent without a lineId is given a new one by the API every time, so to Stock Count a retried request without a lineId looks exactly like another location being counted: a second line carrying the same quantity, and both are added up. With a lineId, the retry replaces the line with the figure it already has, and nothing changes.

With identifiers, repeating a request is harmless: a create for an id that exists changes nothing, and a line for an existing lineId replaces that line. Submitting a count that is already completed does not complete it again.

Planning counts​

EndpointWhat it does
POST /business-units/{businessUnitId}/stock-counts?type=…Create a count: name, start date, optional due date and comment, and — for a cycle count — its saved searches and stock-state filters. See Types of count.
PUT /business-units/{businessUnitId}/stock-counts/{stockCountId}?type=…Change a count's name, dates, comment, saved searches or stock-state filters.
DELETE /business-units/{businessUnitId}/stock-counts/{stockCountId}?type=…Delete a count. Its items are released and nothing is published.
POST /business-units/{businessUnitId}/stock-counts:items-not-counted?type=…Create a count of every item that has moved this year and not been counted this year. CYCLE or TEST.
POST /business-units/{businessUnitId}/stock-counts/{stockCountId}/importCreate a count with an item list you supply. CYCLE (default) or TEST.

A saved search is given either as searchSelectionId — a search selection saved in Product, Price and Promotion — or as query, a search written out directly, plus isMandatory (default false).

Counting​

EndpointWhat it does
PUT /business-units/{businessUnitId}/stock-counts/{stockCountId}/linesRegister or replace one line: item, location, countedQuantity. Returns the deviation thresholds the item's counted total now exceeds.
DELETE /business-units/{businessUnitId}/stock-counts/{stockCountId}/lines/{lineId}Remove a line.
POST /business-units/{businessUnitId}/stock-counts/{stockCountId}/item-categories/{itemCategoryId}:completedMark a category as done: its uncounted mandatory items are registered as 0.
POST /business-units/{businessUnitId}/stock-counts:quick-countCount one item and submit at once — see Quick count.
POST /business-units/{businessUnitId}/stock-counts/{stockCountId}:submit?type=…Submit the count.

About a line:

  • The item is given as itemId, or as itemIdentifier (a barcode such as a GTIN) which Stock Count resolves through Product, Price and Promotion. One of the two is required.
  • A line can be registered for any item, whether or not the count lists it. That is how a control count — which has no list — is counted through the API.
  • location is free text. The app numbers an item's locations 1, 2, 3; an integration can use whatever names mean something in the store. Lines at the same location are separate lines; they are added up with the rest.
  • countedQuantity is zero or more and may have decimals, for items sold by weight or length.
  • The line is stamped with the time it is registered — the request carries no time of its own. That time decides how sales during the count are treated; see Counting while the store is open.
  • Optional batchNumber, serialNumber and businessPartnerId identify what was counted more exactly, and are passed on in the published count. ⚠ Counting one batch of an item counts all of them: when STP applies a count that names batches or serial numbers for an item, it sets every other batch or serial number of that item, not named in the count, to 0. Count every batch of an item in the same count, or none by batch.

Reading counts​

EndpointReturns
GET /business-units/{businessUnitId}/stock-countsThe store's counts. Filter with statuses, startDateFrom/startDateTo, completedDateFrom/completedDateTo; future and completed counts are included only when asked for (doIncludeFutureStockCounts, doIncludeCompletedStockCounts).
GET /business-units/{businessUnitId}/stock-counts/{stockCountId}One count: its settings, status, filters, progress per category, itemsGeneratedDateTime, and its lines (paged with take and skip).
GET /business-units/{businessUnitId}/stock-counts/{stockCountId}/item?itemId=…One item in the count, with its lines. Also accepts itemIdentifier.
GET /business-units/{businessUnitId}/stock-counts/{stockCountId}/items:not-countedThe listed items nobody has counted yet.
GET /business-units/{businessUnitId}/stock-counts/{stockCountId}/item-categoriesThe categories the count's items fall into, with counted and not-counted totals.
GET /business-units/{businessUnitId}/stock-counts/{stockCountId}/item-categories/{itemCategoryId}/itemsThe items of one category, counted and not.
GET /business-units/{businessUnitId}/stock-counts/{stockCountId}/locationsThe locations used in the count so far.

Reports​

The reports compare what was counted with what was expected, per item or per category, valued at the item's cost. They can be read while the count is open as well as after it is completed.

EndpointReturns
GET …/stock-counts/{stockCountId}/counts/categoriesCounted and not-counted items per category.
GET …/stock-counts/{stockCountId}/counts/itemsCounted and expected quantity and value per item.
GET …/stock-counts/{stockCountId}/counts/items:deviationsThe deviation per item, in quantity, percentage and value.

All three can be narrowed to one itemCategoryId. The item reports take doExcludeWithinThreshold=true to leave out every item within the store's deviation thresholds, and take and skip for paging.

Recurring definitions​

EndpointWhat it does
POST /recurring-stock-countsCreate a definition
GET /recurring-stock-countsList the tenant's active definitions
GET /recurring-stock-counts/{recurringStockCountId}Read one definition
PUT /recurring-stock-counts/{recurringStockCountId}Replace a definition
DELETE /recurring-stock-counts/{recurringStockCountId}Stop a definition. Counts it already generated are not affected.
GET /recurring-stock-counts/occurrences?from=…&to=…The dates every definition will generate counts on in the range
GET /recurring-stock-counts/{recurringStockCountId}/occurrences?from=…&to=…The same for one definition

Definitions belong to the tenant, not to a store — the scope inside the definition decides which stores are counted. See Recurring counts.