Update a step’s configuration

This endpoint allows updating the configuration defined for a step of a needs proposal: its productivity rules, employee distribution and staffing limits.

PUT /api/v1/businesses/{businessId}/products/{productId}/needs-config/seasons/{seasonId}/proposals/{proposalId}/steps/{stepId}

The external identifiers of the different entities (business, product, season, proposal and step) must be specified in the request URL.

Below is a detailed explanation of each of the fields that can make up the request body, some of which are required for the request to succeed.

Required fields are marked with an asterisk (*).

Request body

JSON breakdown
{
  "type": "PRODUCTIVITY",
  "productivityBands": [
    {
      "dayType": "string",
      "dayTypeNode": "string",
      "startMinute": 0,
      "duration": 0,
      "salesBrackets": [
        {
          "minSales": 0,
          "maxSales": 0,
          "productivity": 0,
          "minVariable": 0,
          "maxVariable": 0
        }
      ]
    }
  ],
  "employeeDistributionBands": [
    {
      "dayType": "string",
      "dayTypeNode": "string",
      "startMinute": 0,
      "duration": 0,
      "distributions": [
        {
          "totalEmployees": 0,
          "locations": [
            {
              "id": "string",
              "zone": "string",
              "employees": 0
            }
          ]
        }
      ]
    }
  ],
  "employeeLimits": [
    {
      "dayType": "string",
      "dayTypeNode": "string",
      "bands": [
        {
          "startMinute": 0,
          "duration": 0,
          "minPersons": 0,
          "maxPersons": 0
        }
      ]
    }
  ]
}
Details
  • type*: type of the step. Must match the step’s actual type.

  • productivityBands: productivity rules of the step. Each rule includes the following information:

    • dayType*: name of the day type, as returned by the product’s needs configuration.

    • dayTypeNode: external identifier of the node where the day type is defined, as returned by the product’s needs configuration. Only needed when the product has two day types with the same name.

    • startMinute*: minutes since midnight, local time. Values from 1440 onwards represent the early hours of the following day.

    • duration*: duration of the interval in minutes.

    • salesBrackets: brackets for which the productivity rules are defined. Brackets for the same day type cannot overlap. Each bracket includes the following information:

      • minSales*: lower bound of the sales range. One of the band’s brackets must start at 0.

      • maxSales*: upper bound of the sales range. The engine selects the bracket by its lower bound, so the highest one extends to infinity.

      • productivity*: number of employees when the step is of simple productivity, and demand units per employee when it is not.

      • minVariable: lower bound of the bracket’s variable needs. null means there is no limit.

      • maxVariable: upper bound of the bracket’s variable needs. null means there is no limit.

  • employeeDistributionBands: employee distribution rules of the step. Each band includes the following information:

    • dayType*: name of the day type, as returned by the product’s needs configuration.

    • dayTypeNode: external identifier of the node where the day type is defined, as returned by the product’s needs configuration. Only needed when the product has two day types with the same name.

    • startMinute*: minutes since midnight, local time.

    • duration*: duration of the interval in minutes.

    • distributions: distribution by number of employees needed. Brackets for the same day type cannot overlap. Each bracket includes the following information:

      • totalEmployees*: total number of employees to be distributed.

      • locations: distribution of that number of employees across the different tasks. Each task includes the following information:

        • id*: external identifier of the task.

        • zone: external identifier of the task’s zone. If not specified, the service’s default zone will be used.

        • employees*: number of employees assigned to the task.

  • employeeLimits: staffing limits of the step. Each block includes the following information:

    • dayType*: name of the day type, as returned by the product’s needs configuration.

    • dayTypeNode: external identifier of the node where the day type is defined, as returned by the product’s needs configuration. Only needed when the product has two day types with the same name.

    • bands*: limits per time slot. Brackets for the same day type cannot overlap. Each bracket includes the following information:

      • startMinute*: minutes since midnight, local time.

      • duration*: duration of the interval in minutes.

      • minPersons: minimum number of people. null means there is no minimum, but at least one of the two limits must be present.

      • maxPersons: maximum number of people. null means there is no maximum, but at least one of the two limits must be present.

Request example

Once the different fields have been reviewed, an example of the request body is shown below:

PUT /api/v1/businesses/BUSINESSID/products/STORE_0815/needs-config/seasons/SUMMER_2026/proposals/VARIABLE_HOURS/steps/PRODUCTIVITY_SALES
{
    "type": "PRODUCTIVITY",
    "productivityBands": [
        {
            "dayType": "ALL",
            "startMinute": 540,
            "duration": 300,
            "salesBrackets": [
                {
                    "minSales": 0,
                    "maxSales": 400,
                    "productivity": 1
                },
                {
                    "minSales": 400,
                    "maxSales": 1500,
                    "productivity": 2
                }
            ]
        }
    ],
    "employeeDistributionBands": [
        {
            "dayType": "ALL",
            "startMinute": 540,
            "duration": 660,
            "distributions": [
                {
                    "totalEmployees": 1,
                    "locations": [
                        {
                            "id": "03",
                            "employees": 1
                        }
                    ]
                },
                {
                    "totalEmployees": 2,
                    "locations": [
                        {
                            "id": "03",
                            "employees": 1
                        },
                        {
                            "id": "02",
                            "employees": 1
                        }
                    ]
                }
            ]
        }
    ],
    "employeeLimits": [
        {
            "dayType": "ALL",
            "bands": [
                {
                    "startMinute": 540,
                    "duration": 300,
                    "maxPersons": 4
                },
                {
                    "startMinute": 840,
                    "duration": 360,
                    "minPersons": 2,
                    "maxPersons": 5
                }
            ]
        }
    ]
}

If all the request data is correct, the stored configuration of the PRODUCTIVITY_SALES step is completely replaced by the one sent.

Considerations

This request replaces the step’s entire state. Sending an entity as an empty list (or not sending it) deletes the existing configuration. This behavior will be fixed so that, if the entity is not sent or null is sent, the configuration already defined in the system is kept.

The response, if the request is correct, is the state as it has been saved: it has the same structure as the response of the query endpoint.

This request is subject to a feature that must be enabled at business level. If in doubt, it is recommended to check with the Orquest team.

Error codes

In addition to the common errors, this endpoint can return the following codes:

Code Message Description

404 Not Found

The needs configuration write api is not enabled

The needs configuration write feature is not enabled for the business.

The product has no season with that id

The season specified in the URL does not exist.

The proposal is not active in that season

The proposal specified in the URL does not exist.

The proposal has no writable step with that id

The step specified in the URL does not exist in the proposal, or its type is not yet supported by this request.

400 Bad Request

The step '<step>' is of type <type> but the request declares <type>

The type field of the request does not match the step’s actual type.

The step '<step>', productivity band <dayType> [<start>,<end>) has an invalid interval

A productivity rule has startMinute out of range.

The step '<step>', productivity band <dayType> [<start>,<end>) has an invalid interval

A productivity rule has duration out of range. The same message as the previous case is returned, distinguishable only by the cause (INVALID_START_MINUTE versus INVALID_DURATION).

The step '<step>', productivity band <dayType> [<start>,<end>) has an invalid interval

A rule (productivity, distribution or limits) represents an interval that spans more than two days.

The step '<step>', productivity band <dayType> [<start>,<end>) refers to the day type '<dayType>', which the product cannot use

A rule refers to a day type (dayType) that the product cannot use, according to its needs configuration.

The step '<step>', productivity band <dayType> [<start>,<end>) refers to the day type '<dayType>', which the product sees defined on the nodes [<nodes>]; name the node to tell them apart

A rule refers to a day type that the product sees defined on more than one node, without specifying dayTypeNode to distinguish them.

The step '<step>' has overlapping productivity bands for the day type <dayType>: [<start>,<end>) and [<start>,<end>)

Two productivity rules of the same day type overlap.

The step '<step>', productivity band <dayType> [<start>,<end>) has no sales brackets

A productivity rule has no sales bracket (salesBrackets empty).

The step '<step>', productivity band <dayType> [<start>,<end>) has two brackets starting at <value>

Two sales brackets of the same rule start at the same minSales value.

The step '<step>', productivity band <dayType> [<start>,<end>) has no bracket starting at zero sales

No sales bracket of the rule starts at zero.

The step '<step>', productivity band <dayType> [<start>,<end>) has a bracket ending at <value> sales followed by one starting at <value>

Two consecutive sales brackets of the rule leave a gap between them.

The step '<step>', productivity band <dayType> [<start>,<end>) has a bracket with a productivity of <value>

A sales bracket has an invalid productivity value.

The step '<step>', productivity band <dayType> [<start>,<end>) has a bracket with the sales range [<min>,<max>]

A sales bracket has minSales and maxSales that are inconsistent with each other.

The step '<step>', productivity band <dayType> [<start>,<end>) has a bracket with the variable bounds [<min>,<max>]

A sales bracket has minVariable and maxVariable that are inconsistent with each other.

The step '<step>' has overlapping distribution bands for the day type <dayType>: [<start>,<end>) and [<start>,<end>)

Two employee distribution rules of the same day type overlap.

The step '<step>', employee distribution band <dayType> [<start>,<end>) has two brackets for <count> employees

Two distribution brackets of the same rule are defined for the same totalEmployees value.

The step '<step>', employee distribution band <dayType> [<start>,<end>) has no bracket for one employee

No distribution bracket of the rule covers the single-employee case.

The step '<step>', employee distribution band <dayType> [<start>,<end>) goes up to <count> employees but has no bracket for [<count>]

The distribution brackets of the rule leave gaps in the staffing progression (for example, there are brackets for 1, 3 and 4 employees, but not for 2).

The step '<step>', employee distribution band <dayType> [<start>,<end>) gives the location '<location>' <count> employees for a staffing of <count>, fewer than the <count> of a smaller one

A task receives fewer people in a bracket with a higher total staffing than in one with lower staffing.

The step '<step>', employee distribution band <dayType> [<start>,<end>) has a bracket for <count> employees

A distribution bracket has an invalid totalEmployees value, or assigns a negative number of employees to a task in locations.

The step '<step>', employee distribution band <dayType> [<start>,<end>) repeats the location '<location>' in the bracket for <count> employees

A distribution bracket repeats the same task more than once in locations.

The product <product> has no location '<location>' in the zone <zone>

A task specified in locations does not exist in the specified zone, within the product.

The location '<location>' is a system or deleted one, and the needs generator discards it

A task specified in locations is a system task or has been deleted, so the needs generator discards it.

The step '<step>' is not allowed to use the location '<location>'

The step does not support the task specified in locations.

The step '<step>', employee distribution band <dayType> [<start>,<end>) distributes <count> employees over variable locations in the bracket for <count>

The sum of employees distributed across the variable tasks of a bracket does not match its totalEmployees.

The step '<step>' has the day type <dayType> defined twice, and a step can only have one limit per day type

There are two employeeLimits blocks for the same day type.

The step '<step>', employee limits of <dayType> has no bands

A limits block has no rules (bands empty).

The step '<step>', employee limits of <dayType> has overlapping bands: [<start>,<end>) and [<start>,<end>)

Two rules of the same limits block overlap.

The step '<step>', employee limits of <dayType> has a band [<start>,<end>) with neither a minimum nor a maximum

A limits rule has neither minPersons nor maxPersons.

The step '<step>', employee limits of <dayType> has a band [<start>,<end>) with a negative limit

A limits rule has a negative value in minPersons or maxPersons.

The step '<step>', employee limits of <dayType> has a band [<start>,<end>) whose minimum <value> is above its maximum <value>

A limits rule has minPersons greater than maxPersons.

What are needs?

What is a needs generator?