Get Inventory
Provide at least one of ProductIds or LocationIds. Each filter may contain one or more Wholechain IDs; provide both filters to return matching inventory only.
curl -X GET "https://connect.wholechain.com/Integration/Inventory?ProductIds=973&LocationIds=loc_110" \
-H "Content-Type: application/json" \
-H "X-API-KEY: example_string" \
-H "accept: text/plain"
import requests
import json
url = "https://connect.wholechain.com/Integration/Inventory?ProductIds=973&LocationIds=loc_110"
headers = {
"Content-Type": "application/json",
"X-API-KEY": "example_string",
"accept": "text/plain"
}
response = requests.get(url, headers=headers)
print(response.json())
const response = await fetch("https://connect.wholechain.com/Integration/Inventory?ProductIds=973&LocationIds=loc_110", {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "example_string",
"accept": "text/plain"
}
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "https://connect.wholechain.com/Integration/Inventory?ProductIds=973&LocationIds=loc_110", nil)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-KEY", "example_string")
req.Header.Set("accept", "text/plain")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://connect.wholechain.com/Integration/Inventory?ProductIds=973&LocationIds=loc_110')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Content-Type'] = 'application/json'
request['X-API-KEY'] = 'example_string'
request['accept'] = 'text/plain'
response = http.request(request)
puts response.body
{
"products": [
{
"productId": "PROD-1",
"productName": "Product 1",
"lots": [
{
"lotSerial": "Lot A",
"inventory": [
{
"locationId": "LOC-1",
"locationName": "Warehouse 1",
"quantityAvailable": 100,
"eventDate": "2026-01-02T10:00:00Z"
},
{
"locationId": "LOC-1",
"locationName": "Warehouse 1",
"quantityAvailable": 200,
"eventDate": "2026-01-05T14:30:00Z"
}
]
}
]
}
]
}
/Integration/Inventory
Target server for requests. Edit to use your own host.
One or more Wholechain product IDs. Provide this or LocationIds. To filter by several IDs, repeat the parameter.
One or more Wholechain location IDs. Provide this or ProductIds. To filter by several IDs, repeat the parameter.
Your Wholechain API key.
Response content type.
Request Preview
Response
Response will appear here after sending the request
Responses
Introduction
Retrieve Wholechain inventory for one or more products and/or locations.
The Inventory endpoint returns inventory grouped by product, lot/serial number, and location, including the reconstructed inventory history for each lot.
Authentication
This endpoint requires your Wholechain API key to be included in the X-API-KEY request header.
Example Request
curl -X GET \
"https://connect.wholechain.com/Integration/Inventory?ProductIds=973&LocationIds=loc_110" \
-H "accept: text/plain" \
-H "X-API-KEY: <YOUR_API_KEY>"
Query Parameters
| Parameter | Description |
|---|---|
ProductIds | One or more Wholechain Product IDs used to filter inventory by product. |
LocationIds | One or more Wholechain Location IDs used to filter inventory by location. |
At least one of these parameters must be supplied.
To filter by several IDs, repeat the parameter: ?ProductIds=973&ProductIds=974. JSON arrays and comma-separated lists are not supported.
You can query inventory using:
- Product ID only — returns inventory for the specified product across all locations.
- Location ID only — returns inventory for all products held at the specified location.
- Product ID and Location ID — returns inventory matching both filters.
Example: Product Only
GET /Integration/Inventory?ProductIds=973
Example: Location Only
GET /Integration/Inventory?LocationIds=loc_110
Example: Product and Location
GET /Integration/Inventory?ProductIds=973&LocationIds=loc_110
Response
The response is grouped by:
Product
└── Lot / Serial
└── Inventory by Location and Event Date
Example Response
{
"products": [
{
"productId": "PROD-1",
"productName": "Product 1",
"lots": [
{
"lotSerial": "Lot A",
"inventory": [
{
"locationId": "LOC-1",
"locationName": "Warehouse 1",
"quantityAvailable": 100,
"eventDate": "2026-01-02T10:00:00Z"
},
{
"locationId": "LOC-1",
"locationName": "Warehouse 1",
"quantityAvailable": 200,
"eventDate": "2026-01-05T14:30:00Z"
},
{
"locationId": "LOC-2",
"locationName": "Cold Storage",
"quantityAvailable": 500,
"eventDate": "2026-01-03T09:00:00Z"
}
]
}
]
}
]
}
Response Fields
Each inventory record contains:
| Field | Description |
|---|---|
locationId | Wholechain ID of the location where the inventory is held. |
locationName | Name of the location where the inventory is held. |
quantityAvailable | Quantity that remains available for the product and lot during that point in the reconstructed inventory timeline. |
eventDate | Date and time from which that inventory state applies. |
Understanding Inventory History
Wholechain inventory is determined from the complete sequence of inventory-affecting events associated with a product and lot.
Inventory may change through events such as:
- Receives
- Shipments
- Transformations
- Inventory adjustments
- Decommission events
- Other inventory-affecting events
A key point is that quantityAvailable represents the quantity that is still available after the full inventory timeline has been taken into account.
It should therefore not be interpreted simply as:
“How much inventory physically existed immediately after this event?”
Instead, it represents:
“How much of this inventory remains available for another event at this point in the timeline?”
This is important because inventory used by a later event can reduce the quantity available to earlier points in the timeline.
Example
Assume 100 units are received on:
2 Jan 2026 10:00
If no later events consume that inventory, the available quantity is:
2 Jan 2026 10:00 → 100 units available
Now assume 50 of those units are shipped on:
4 Jan 2026 12:00
Those 50 units are now part of the 4 January shipment and are no longer available to be consumed by another event.
The inventory available between the receive and the shipment therefore becomes:
2 Jan 2026 10:00 → 50 units available
4 Jan 2026 12:00 → 50 units have been shipped
This means that if another Ship or Transform event is submitted with an event timestamp of 3 January, Wholechain should only consider 50 units available, not 100.
The other 50 units are already accounted for by the shipment occurring on 4 January.
This prevents the same inventory from being consumed twice.
Selecting Inventory for an Event
When validating or creating an event, use the inventory record whose eventDate is the latest date that is less than or equal to the event timestamp.
For example, if the inventory response contains:
2 Jan 2026 10:00 → 50 units available
5 Jan 2026 14:30 → 150 units available
and you are creating an event for:
4 Jan 2026 09:00
the applicable inventory record is:
2 Jan 2026 10:00 → 50 units available
because this is the latest inventory record applicable before the event timestamp.
Historical Inventory Recalculation
Wholechain supports inventory-affecting events being inserted historically.
When a historical event is added, Wholechain recalculates the relevant inventory timeline so that inventory already consumed by that event is no longer available to other events in the affected period.
Example
Assume the inventory history initially contains:
| Event Date | Quantity Available |
|---|---|
| 2 Jan 2026 10:00 | 100 |
| 5 Jan 2026 14:30 | 200 |
Now assume a historical Ship event for 50 units is created with an event date of:
4 Jan 2026
Wholechain recalculates the inventory timeline.
The resulting history becomes:
| Event Date | Quantity Available |
|---|---|
| 2 Jan 2026 10:00 | 50 |
| 5 Jan 2026 14:30 | 150 |
The historical shipment affects both inventory records.
The 2 January quantity changes from 100 to 50 because 50 units are now accounted for by the shipment on 4 January.
This is important if another event is subsequently inserted between 2 January and 4 January. That event must not be allowed to consume the same 50 units that have already been used by the 4 January shipment.
For example:
2 Jan Receive 100
│
│ 50 available for another event
│
3 Jan New Ship?
│
│ Maximum available = 50
│
4 Jan Existing Ship 50
Although 100 units were originally received on 2 January, only 50 remain available for another event occurring during that period because the other 50 have already been consumed by the 4 January shipment.
The same effect is carried forward to later inventory records.
The 5 January quantity therefore changes from 200 to 150.
This reconstructed approach prevents duplicate consumption of the same inventory and ensures that every event in the supply chain timeline can be validated against the quantity that genuinely remains available.
Typical Use Cases
The Inventory endpoint can be used to:
- Determine whether sufficient inventory is available before creating a Ship or Transform event.
- Retrieve inventory associated with a particular location.
- Find the locations where a particular product and lot have available inventory.
- Determine the inventory available for a product and lot at a particular point in the event timeline.
- Validate historical events against inventory that remains available at the event timestamp.
- Prevent the same product inventory from being consumed by multiple events.