Demand-Driven Replenishment

This page is outdated. Please go to our new documentation under https://docs.fulfillmenttools.com/documentation.

Summary

This page describes use cases where replenishments for items are made in specific time intervals based on demand or where products can be produced on demand. In that case, systems should often allow customer orders to be accepted without being limited by current stock levels until the point in time when the purchase order is placed or production schedules are defined.

Use Case Examples

Short replenishment cycles

A company offers lots of seasonal products which, naturally, are subject to high fluctuations in demand. In addition, these products can be replenished in a short time and the user knows already when orders will arrive. Thus, purchasing agents monitor already accepted customer orders and place purchase orders based on demand to avoid over-stock. As a result, there is no stock limit on the number of customer orders that can be accepted until the purchase order is placed.

Internal production facility

A company produces some goods internally. To prevent overproduction, the production schedule is made based on current demand levels. As a result, there is no stock limit on the number of customer orders that can be accepted until the production schedule is defined.

Implementation in fulfillmenttools

The described use case is mapped by creating purchase orders with a very high amount of products and allowing shop systems to access the thereby created expected stock.

1. Create listings for products that should be available in large quantities

In most set-ups, listings should already be created for all products that are managed via fulfillmenttools' systems. Still, make sure that a listing exists for each relevant product. If goods are perishable and/or should only be available for a certain time frame, stockProperties and/or stockAvailableUntil must be configured. See here for more details.

Create or Update listings of a facility with the given ID

put
Authorizations
Path parameters
facilityIdstringRequired

ID of facility you want to get its listing

Body
Responses
200

Facility listing was found & you were allowed to access it.

No content

put
/api/facilities/{facilityId}/listings
PUT /api/facilities/{facilityId}/listings HTTP/1.1
Host: %%HOST%%/
Authorization: Bearer YOUR_OAUTH2_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 529

{
  "listings": [
    {
      "attributes": [
        {
          "category": "descriptive",
          "key": "%%subtitle%%",
          "priority": 100,
          "value": "585er Gold"
        }
      ],
      "imageUrl": "text",
      "price": 1200,
      "tenantArticleId": "4711",
      "title": "Adidas Superstar",
      "weight": 1,
      "scanningRule": {
        "values": []
      },
      "scannableCodes": [
        "text"
      ],
      "outOfStockBehaviour": "BACKORDER",
      "availabilityTimeframe": {
        "start": "2020-02-03T08:45:50.525Z"
      },
      "tags": [],
      "measurementUnitKey": "liter",
      "stockProperties": {
        "ANY_ADDITIONAL_PROPERTY": {
          "inputType": "DATE",
          "required": true,
          "defaultValue": "text"
        }
      },
      "legal": {
        "hsCode": "text"
      }
    }
  ]
}

No content

Example call for creating listing
{
  "listings": [
    {
      "tenantArticleId": "4711",
      "title": "Chocolate Santa",
      "titleLocalized": {
        "de_DE": "Schoko Weihnachtsmann",
        "en_US": "Chocolate Santa"
      },
      "stockProperties": {
        "expiry": {
          "inputType": "DATE",
          "required": true
        }
      },
      "stockAvailableUntil": {
        "calculationBase": "EXPIRY",
        "modifier": "-P30D"
      }
      "version": 1
    }
  ]
}

2. Create a purchaseOrder

Create a purchaseOrder including all items that have not been ordered yet but should be already available for sale and not be limited by current stock levels.

  • Choose a high number for the quantity.value of requestedItems

  • Define the date when the delivery is expected to arrive in requestedDate.value and set requestedDate.type to "TIMEPOINT"

  • Include as many items as possible in one purchaseOrder rather than creating one purchaseOrder for each item for that a very high stock should be assumed. However, please consider the limit of 200 tenantArticleIds per purchaseOrder.

Create purchase order

post
Authorizations
Body

PurchaseOrderForCreation

cancelledbooleanOptionalDeprecated

This field is deprecated. Set the status to 'CANCELED' Set the purchaseOrder to 'cancelled'. No further deliveries will be expected. Already received goods are unaffected.

customAttributesobject | nullableOptional

Attributes that can be added to this entity. These attributes cannot be used within fulfillment processes, but enable you to attach custom data from your systems to fulfillmenttools entities.

facilityRefstring · min: 1Required
orderDatestring · date-timeRequired

Time and date at which the order was placed. Note: This does not refer to the creation date of this entity in the system.

requestedDateall ofRequired

Time and date at which the order is expected to arrive. Use 'ASAP' for deliveries with unknown date, but be aware that some features will not include these orders.

statusstring · enumOptionalPossible values:
Responses
201

Created Purchase Order entity

application/json
post
/api/purchaseorders
POST /api/purchaseorders HTTP/1.1
Host: your-tenant-name.api.fulfillmenttools.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 334

{
  "customAttributes": {},
  "facilityRef": "text",
  "orderDate": "2025-11-10T10:44:17.630Z",
  "requestedDate": {
    "type": "ASAP",
    "value": "2025-11-10T10:44:17.630Z"
  },
  "requestedItems": [
    {
      "customAttributes": {},
      "quantity": {
        "unit": "text",
        "value": 1
      },
      "stockProperties": {
        "expiry": "text"
      },
      "tenantArticleId": "text"
    }
  ],
  "status": "OPEN",
  "supplier": {
    "name": "text"
  }
}
{
  "created": "2025-11-10T10:44:17.630Z",
  "customAttributes": {},
  "facilityRef": "text",
  "id": "text",
  "inboundProcessRef": "text",
  "lastModified": "2025-11-10T10:44:17.630Z",
  "orderDate": "2025-11-10T10:44:17.630Z",
  "requestedDate": {
    "type": "ASAP",
    "value": "2025-11-10T10:44:17.630Z"
  },
  "requestedItems": [
    {
      "customAttributes": {},
      "quantity": {
        "unit": "text",
        "value": 1
      },
      "stockProperties": {
        "expiry": "text"
      },
      "tenantArticleId": "text"
    }
  ],
  "status": "OPEN",
  "supplier": {
    "name": "text"
  },
  "transfer": {
    "id": "text"
  },
  "version": 1
}
Example query for creating purchaseOrder
{
  "orderDate": "2024-08-12T12:59:37.192Z",
  "requestedDate": {
    "type": "TIME_POINT",
    "value": "2024-08-19T12:59:37.192Z"
  },
  "requestedItems": [
    {
      "tenantArticleId": "4711",
      "quantity": {
        "value": 10000
      },
      "stockProperties": {
        "expiry": "2025-02-19T12:59:37.192Z"
      }
    }
  ],
  "facilityRef": "warehouse-cgn"
}

3. Enable shop systems to communicate expected stock in sales availability

Use one of the below endpoints to query stock availability in your shop's detail pages and in the checkout journey. By that, it is ensured that expected stock is considered in the shop availability. Go here to get more information on the checkout options endpoints.

Get earliest delivery

post

Get earliest delivery timepoint for a given checkoutOption

Authorizations
Body

CheckoutOptionsDeliveryEarliestRequest

consumerAddressall ofRequired

Consumer delivery address

earliestDeliveryDatestring · date-timeOptional

Earliest delivery date

filterall ofOptional

Facility filter criteria

includeCalculationHintsbooleanOptional

Whether to include calculation hints in the response

includeListingDetailsbooleanOptional

Indicates whether listing-related details should be included in the response. If set to true, the response contains additional listing details. Defaults to false.

tenantArticleIdsstring[] · min: 1Required

List of tenant article IDs

Responses
200

The request could be evaluated

application/json
post
/api/promises/checkoutoptions/delivery/earliest
POST /api/promises/checkoutoptions/delivery/earliest HTTP/1.1
Host: your-tenant-name.api.fulfillmenttools.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 327

{
  "consumerAddress": {
    "addressType": "POSTAL_ADDRESS",
    "city": "text",
    "country": "DE",
    "houseNumber": "text",
    "postalCode": "text",
    "province": "text",
    "street": "text"
  },
  "earliestDeliveryDate": "2025-11-10T10:44:17.630Z",
  "filter": {
    "customAttributes": {}
  },
  "includeCalculationHints": true,
  "includeListingDetails": true,
  "tenantArticleIds": [
    "text"
  ]
}
{
  "calculationHints": [
    "text"
  ],
  "checkoutOptions": [
    {
      "availableCarriers": [
        {
          "carrierRef": "text",
          "latestPickingStartDate": "2025-11-10T10:44:17.630Z",
          "name": "text",
          "nonDeliveryDays": [
            "text"
          ]
        }
      ],
      "availableFacilityConnections": [
        {
          "connectionRef": "text",
          "latestPickingStartDate": "2025-11-10T10:44:17.630Z",
          "nonDeliveryDays": [
            "text"
          ]
        }
      ],
      "earliestPredictedDeliveryDate": "2025-11-10T10:44:17.630Z",
      "listingDetails": [
        {
          "customAttributes": {},
          "facilityRef": "text",
          "tenantFacilityId": "text"
        }
      ],
      "tenantArticleId": "text"
    }
  ]
}

Get delivery time period

post
Authorizations
Body

CheckoutOptionsDeliveryTimePeriodRequest

consumerAddressall ofRequired

Consumer delivery address

endDatestring · date-timeOptional

End date-time of the period

includeCalculationHintsbooleanOptional

Whether to include calculation hints in the response

startDatestring · date-timeOptional

Start date-time of the period

Responses
200

The request could be evaluated

application/json
post
/api/promises/checkoutoptions/delivery/timeperiod
POST /api/promises/checkoutoptions/delivery/timeperiod HTTP/1.1
Host: your-tenant-name.api.fulfillmenttools.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 543

{
  "basket": [
    {
      "quantity": 1,
      "tenantArticleId": "text"
    }
  ],
  "consumerAddress": {
    "addressType": "POSTAL_ADDRESS",
    "city": "text",
    "country": "DE",
    "houseNumber": "text",
    "postalCode": "text",
    "province": "text",
    "street": "text"
  },
  "deliveryPreferences": {
    "carrierProductCategory": "STANDARD",
    "desiredDeliveryTime": "2020-02-03T09:45:51.525Z",
    "preferredCarriers": [
      "text"
    ],
    "preferredCarriersWithProduct": [],
    "preselectedFacilities": [
      null
    ],
    "serviceLevel": "DELIVERY"
  },
  "endDate": "2025-11-10T10:44:17.630Z",
  "includeCalculationHints": true,
  "startDate": "2025-11-10T10:44:17.630Z"
}
{
  "calculationHints": [
    "text"
  ],
  "checkoutOptions": [
    {
      "availableCarriers": [
        {
          "carrierRef": "text",
          "latestPickingStartDate": "2025-11-10T10:44:17.630Z",
          "name": "text",
          "nonDeliveryDays": [
            "text"
          ]
        }
      ],
      "availableFacilityConnections": [
        {
          "connectionRef": "text",
          "latestPickingStartDate": "2025-11-10T10:44:17.630Z",
          "nonDeliveryDays": [
            "text"
          ]
        }
      ],
      "date": "2025-11-10T10:44:17.630Z",
      "overallStatus": "ALL"
    }
  ]
}

Get delivery timepoint

post

This endpoint is to be used to get information about the possible delivery of items.

Authorizations
Body

CheckoutOptionsDeliveryTimePointRequest

desiredDeliveryDatestring · date-timeRequired

Desired delivery date-time

tenantArticleIdsstring[]Required

Tenant article IDs

Responses
200

The request could be evaluated

application/json
post
/api/promises/checkoutoptions/delivery/timepoint
POST /api/promises/checkoutoptions/delivery/timepoint HTTP/1.1
Host: your-tenant-name.api.fulfillmenttools.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 164

{
  "desiredDeliveryDate": "2025-11-10T10:44:17.630Z",
  "facilities": [
    {
      "facilityRef": "text",
      "latestPickingStart": "2025-11-10T10:44:17.630Z"
    }
  ],
  "tenantArticleIds": [
    "text"
  ]
}
{
  "items": [
    {
      "available": 1,
      "facilityRef": "text",
      "latestPickingStart": "2025-11-10T10:44:17.630Z",
      "tenantArticleId": "text"
    }
  ]
}

4. Create a new purchaseOrder

Before patching the existing purchaseOrder (created in step 2) with the actually ordered quantity, a new purchaseOrder with large quantities needs to be created. This ensures that the systems can already accept customer orders that should be fulfilled within next production or replenishment cycle. See step 2 for this.

5. Patch purchaseOrder with actual quantity

Once the purchase order was placed or the production schedule was defined, patch requested items in purchase order with quantities that were actually ordered or planned to be produced. Adjust stock properties such as expiry date if necessary.

If there are more reservations than (expected) stock for reasons such as problems during production or defective items in a delivery, our systems try to distribute these abandoned reservations to other stock. If no alternative stock is available, the reservation is still tracked and will be shifted to a stock as soon as some stock becomes available.

Updates purchase order

patch

Partially updates a Purchase Order using a selection of fields

Authorizations
Path parameters
purchaseOrderIdstringRequired
Body

PurchaseOrderForPartialUpdate

cancelledbooleanOptionalDeprecated

This field is deprecated. Set the status to 'CANCELED' Set the purchaseOrder to 'cancelled'. No further deliveries will be expected. Already received goods are unaffected.

customAttributesobject | nullableOptional

Attributes that can be added to this entity. These attributes cannot be used within fulfillment processes, but enable you to attach custom data from your systems to fulfillmenttools entities.

orderDatestring · date-timeOptional
statusstring · enumOptionalPossible values:
versionnumberRequired
Responses
200

Updated Purchase Order entity

application/json
patch
/api/purchaseorders/{purchaseOrderId}
PATCH /api/purchaseorders/{purchaseOrderId} HTTP/1.1
Host: your-tenant-name.api.fulfillmenttools.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 325

{
  "customAttributes": {},
  "orderDate": "2025-11-10T10:44:17.630Z",
  "requestedDate": {
    "type": "ASAP",
    "value": "2025-11-10T10:44:17.630Z"
  },
  "requestedItems": [
    {
      "customAttributes": {},
      "quantity": {
        "unit": "text",
        "value": 1
      },
      "stockProperties": {
        "expiry": "text"
      },
      "tenantArticleId": "text"
    }
  ],
  "status": "OPEN",
  "supplier": {
    "name": "text"
  },
  "version": 1
}
{
  "created": "2025-11-10T10:44:17.630Z",
  "customAttributes": {},
  "facilityRef": "text",
  "id": "text",
  "inboundProcessRef": "text",
  "lastModified": "2025-11-10T10:44:17.630Z",
  "orderDate": "2025-11-10T10:44:17.630Z",
  "requestedDate": {
    "type": "ASAP",
    "value": "2025-11-10T10:44:17.630Z"
  },
  "requestedItems": [
    {
      "customAttributes": {},
      "quantity": {
        "unit": "text",
        "value": 1
      },
      "stockProperties": {
        "expiry": "text"
      },
      "tenantArticleId": "text"
    }
  ],
  "status": "OPEN",
  "supplier": {
    "name": "text"
  },
  "transfer": {
    "id": "text"
  },
  "version": 1
}
Example query for patching purchaseOrder
{
  "version": 2,
  "requestedItems": [
    {
      "tenantArticleId": "4711",
      "quantity": {
        "value": 150
      },
      "stockProperties": {
        "expiry": "2025-02-19T12:59:37.192Z"
      }
    }
  ],
  "facilityRef": "warehouse-cgn"
}

6. Create stock after delivery has arrived or products are produced

If the delivery of the ordered products has arrived or the production was finished, a receipt needs to be added to the inbound process of the purchase order to create stock. Use the GET /api/purchaseorders/{purchaseOrderId} endpoint to query the inboundProcessRef if not sure about the inboundProcess that the purchase order belongs to.

Create inbound process receipt

post

This part of the API is in Beta status. For details please check the api-release-life-cycle documentation.Adds a receipt to an inbound process.

Authorizations
Path parameters
inboundProcessIdstringRequired
Body

InboundReceiptForCreation

asnRefstringOptional

enables mapping a receipt to one of the ASNs in this inbound process

customAttributesobject | nullableOptional

Attributes that can be added to this entity. These attributes cannot be used within fulfillment processes, but enable you to attach custom data from your systems to fulfillmenttools entities.

receivedDatestring · date-timeRequired

date-time of the arrival of the items in the facility

statusstring · enumOptional

status of this receipt, only receipts with status 'FINISHED' are booked. IN_PROGRESS can be used to save partial receipts.

Possible values:
Responses
201

Receipt was added to the inbound process

application/json
post
/api/inboundprocesses/{inboundProcessId}/receipts
POST /api/inboundprocesses/{inboundProcessId}/receipts HTTP/1.1
Host: your-tenant-name.api.fulfillmenttools.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 416

{
  "asnRef": "text",
  "comments": [
    {
      "content": "text",
      "userRef": "text"
    }
  ],
  "customAttributes": {},
  "receivedDate": "2025-11-10T10:44:17.630Z",
  "receivedItems": [
    {
      "acceptedQuantity": {
        "unit": "text",
        "value": 1
      },
      "comments": [
        {
          "content": "text",
          "userRef": "text"
        }
      ],
      "customAttributes": {},
      "rejectedQuantity": {
        "unit": "text",
        "value": 1
      },
      "stockProperties": {
        "expiry": "text"
      },
      "storageLocationRef": "text",
      "tenantArticleId": "text"
    }
  ],
  "status": "OPEN"
}
{
  "asnRef": "text",
  "comments": [
    {
      "content": "text",
      "documentSetRef": "text",
      "id": "text",
      "userRef": "text"
    }
  ],
  "customAttributes": {},
  "id": "text",
  "receivedDate": "2025-11-10T10:44:17.630Z",
  "receivedItems": [
    {
      "acceptedQuantity": {
        "unit": "text",
        "value": 1
      },
      "comments": [
        {
          "content": "text",
          "documentSetRef": "text",
          "id": "text",
          "userRef": "text"
        }
      ],
      "customAttributes": {},
      "id": "text",
      "rejectedQuantity": {
        "unit": "text",
        "value": 1
      },
      "stockProperties": {
        "expiry": "text"
      },
      "storageLocationRef": "text",
      "tenantArticleId": "text"
    }
  ],
  "status": "OPEN"
}

Example query for adding a receipt to an inboundProcess
{
  "receivedDate": "2024-08-18T13:40:05.864Z",
  "receivedItems": [
    {
      "tenantArticleId": "4711",
      "acceptedQuantity": {
        "value": 149
      },
      "rejectedQuantity": {
        "value": 1
      },
      "stockProperties": {
        "expiry": "2025-02-19T12:59:37.192Z"
      },
      "comments": [
        {
          "content": "One item was broken.",
        }
      ],
    }
  ],
  "status": "FINISHED"
}

Last updated

Was this helpful?