Recurring counts
A recurring definition is a plan for counts that repeat: "count frozen goods in every store every two weeks", "full count in the Stockholm region on these three dates". Stock Count turns each definition into ordinary, dated counts — one per store, each time an occurrence falls due — and those counts are counted and submitted like any other.
A definition is not itself a count. Nothing is counted against it, and deleting it does not touch the counts it has already generated.
What a definition holds
| Field | Meaning |
|---|---|
name | Optional. Generated counts are named after it; without one they are called Recurring count followed by the date. |
scopeLevel and scopeId | Who is counted: TENANT (every store; no scopeId), GROUP (every store at or below a business-unit group), or BU (one store). |
stockCountType | FULL, CYCLE or CONTROL. Defaults to CYCLE. Test counts cannot recur. |
frequencyType | INTERVAL — every intervalCount × intervalUnit (DAY, WEEK, MONTH, YEAR), counted from anchorDate — or CUSTOM_DATES — the listed customDates. |
anchorDate | The date of the first occurrence. Required for INTERVAL. |
countWindowDays | How many days each generated count stays open: it starts on its occurrence date and is due this many days later. |
recurrenceEndDate | Optional. No occurrence is generated after it. |
filters | Saved searches, exactly as on a cycle count, and validated by the same rules as a count of the same type. |
stockFilters | Stock-state filters, carried into every generated count. |
There is no "does not repeat" frequency: a one-off count is simply a count with a future start date.
Dates never drift. Every occurrence is calculated from the anchor, not from the previous occurrence. A monthly definition anchored on 31 January generates 28 February, 31 March, 30 April and so on — the short month does not pull every later date back to the 28th.
Two example definitions
A definition reads like a recipe: what to count, where, how often, and for how many days each count stays open.
| Paint, every quarter | Whole store, once a year | |
|---|---|---|
| Type | CYCLE | FULL |
| What | the items the saved search Paint finds | every item worth counting — a full count takes no filters |
| Mandatory | yes — an item nobody counts becomes 0 | always, in a full count |
| Where | every store in the group Region North | every store in the tenant |
| First occurrence | 4 January 2027 | 1 September 2027 |
| Repeats | every 3 months | every year |
| Open for | 7 days | 3 days |
| Ends | never | never |
{
"recurringStockCountId": "paint-quarterly-region-north",
"name": "Paint, every quarter",
"scopeLevel": "GROUP",
"scopeId": "region-north",
"stockCountType": "CYCLE",
"frequencyType": "INTERVAL",
"intervalCount": 3,
"intervalUnit": "MONTH",
"anchorDate": "2027-01-04",
"countWindowDays": 7,
"filters": [{ "searchSelectionId": "saved-search-paint", "isMandatory": true }]
}
{
"recurringStockCountId": "full-count-yearly",
"name": "Whole store, once a year",
"scopeLevel": "TENANT",
"stockCountType": "FULL",
"frequencyType": "INTERVAL",
"intervalCount": 1,
"intervalUnit": "YEAR",
"anchorDate": "2027-09-01",
"countWindowDays": 3
}
On the calendar, each generated count is a bar as wide as the days it stays open:
GET /recurring-stock-counts/occurrences returns exactly these dates before any count exists — see
Seeing what is coming.
How counts are generated
Every night at 01:15 UTC — a fixed time, so daylight saving does not move it — Stock Count evaluates every active definition:
- Is an occurrence due today? From the anchor, the interval or the list of dates, and the end date.
- Which stores does it cover? A tenant or group scope is resolved to its stores at that moment, so a store opened last week is included and a closed one is not. Only active physical stores receive counts — warehouses and closed stores are skipped. A store-scoped definition for a store that has since closed generates nothing.
- For each store, a count is created with the definition's type and a copy of its filters, starting
on the occurrence date and due
countWindowDayslater. Its item list is built straight away, by the same rules as any count.
⚠ The next occurrence is skipped while the previous one is still open. If the count a definition generated for a store two weeks ago has not been submitted or deleted, no new count is generated for that store — the store would otherwise pile up counts it has not started. Other stores under the same definition are unaffected. A definition that seems to have stopped generating for one store usually has an open count there.
A skipped occurrence is not made up later. Each night evaluates only that day's occurrences, so when the late count is finally submitted, the definition simply carries on with its next date. And nothing closes a count because its window has passed — only submitting or deleting it does.
Running the evaluation twice on the same day does not create duplicates, and an evaluation that fails part-way through is retried and completes only what is missing.
Every occurrence picks its own list
A definition is a template, not a list. Each generated count builds its list on the night it opens, by the same rules as any other count — from the store's stock at that moment, and from what has happened to each item since it was last counted. So the same definition lists different items each time:
Red 1 L was counted as 0 in January and has not moved since: it is settled, so April's count leaves it out. Green 1 L arrived in February: it holds stock now, so it is on the list. This is also why recurring counts need the stock to be held in STP — see Stock ownership.
Definitions add up
A store runs every definition that applies to it: the tenant-wide one, each group definition that covers one of its groups, and its own. Each due definition produces its own count. A store-level definition does not replace a broader one — a store covered by a tenant, a group and a store definition that all fall due on the same day gets three counts that day.
A group definition covers every store at or below the group, however deep the hierarchy. The warehouse gets nothing, even under a tenant-wide definition: only active physical stores are counted.
Every generated count records which definition produced it.
One item, one count
Because a store can get several counts on the same day, the same item often qualifies for more than one. It is placed in exactly one of them:
- The broadest definition wins. Among the counts generated for a store together, a shared item goes to the count from the tenant definition first, then the group definitions — a group higher in the hierarchy before one below it — then the store's own. The narrower counts get what is left. Where two definitions have the same scope, the placement is deterministic, so generating again gives the same result.
- Counts already open keep their items. An item listed by a count opened before today — a manual count from yesterday, or last week's occurrence — stays there. It is not moved, and nothing in a count a store has started is taken away from it.
- A completed or deleted count releases its items, and they can be picked up by the next count that qualifies them.
Seeing what is coming
GET /recurring-stock-counts/occurrences?from=…&to=… lists, for every active definition, the dates it
will generate counts on in that range, with the due date each implies. The dates are exactly the
dates the nightly evaluation uses. The contents of a future count are not known in advance — which
items qualify depends on the stock and the other counts at the time it is generated.
GET /recurring-stock-counts/{recurringStockCountId}/occurrences does the same for one definition.
Managing definitions
Definitions are created, replaced and deleted through the API. Like
every write to Stock Count, the request is accepted with 202 and applied a moment later. Deleting a
definition stops it from generating; the counts it already created stay as they are.
Read next
- Types of count — how each generated count builds its item list
- The API — the recurring-definition endpoints
- Events — a generated count is announced like any other new count