Understanding Event Responses
Introduction
When submitting events to the Wholechain Events API, the response tells you what happened to:
- The event
- The product instances involved in the event
- Any locations submitted with the request
- Any products submitted with the request
- Direct Ship fallback processing
- Errors or validations
A successful response may look similar to:
{
"message": "Events processed successfully",
"result": [
{
"id": "01a0d87d-e737-72ec-adbf-02af9fc236ae",
"externalEventId": "ship-evt-2025071501",
"type": "Ship",
"status": "Created",
"eventDate": "2025-07-15T09:30:00+00:00",
"productInstances": [
{
"quantity": 75,
"lotSerial": "LOT-SHIP-2025071501",
"status": "Created",
"id": "01a0d87d-e737-784e-be4c-90eaf85d37a8",
"name": "Atlantic Salmon Fillet 10lb",
"urn": "urn:gdst:wholechain.com:product:lot:class:raindropsolutions.atlanticsalmonfillet10lb.lot-ship-2025071501"
}
],
"containers": [],
"directShipFallback": {
"reason": "MissingInventory",
"missingLots": [
{
"lotSerial": "LOT-SHIP-2025071501",
"productIdentifier": "prod_atlantic_salmon_fillet_10lb",
"requestedQuantity": 75,
"missingQuantity": 75
}
]
},
"externalShipmentFailure": null
}
],
"locations": [],
"products": [],
"errors": [],
"validations": []
}
Response Structure
A standard event response contains several different levels of information:
Response
│
├── result
│ └── Event
│ ├── Event Status
│ ├── Event Date
│ ├── Product Instances
│ ├── Containers
│ ├── Direct Ship Fallback
│ └── External Shipment Failure
│
├── locations
│ └── Location Status
│
├── products
│ └── Product Status
│
├── errors
│
└── validations
It is important to review the entire response rather than only checking the top-level message.
For example:
"message": "Events processed successfully"
means that Wholechain processed the request.
You should still review the status returned for the individual event, products, locations, and any fallback information.
Event-Level Status
Each processed event contains its own status.
For example:
{
"externalEventId": "ship-evt-2025071501",
"type": "Ship",
"status": "Created"
}
The event status tells you what Wholechain did with that specific event.
The primary statuses are:
| Status | Meaning |
|---|---|
Created | The Event ID did not previously exist and a new event was created. |
Skipped | The Event ID already exists, but event updates are not enabled for the Wholechain account. The existing event is therefore left unchanged. |
Updated | The Event ID already exists, updates are enabled, and Wholechain updated the existing event based on the new payload. |
Created
Created means Wholechain did not find an existing event with that Event ID.
A new event was therefore created.
For example:
{
"externalEventId": "SHIP-001",
"type": "Ship",
"status": "Created"
}
Conceptually:
SHIP-001
Does not exist
↓
Payload submitted
↓
New event created
↓
status: Created
The externalEventId is therefore particularly important because it allows Wholechain to determine whether the request represents a new event or an event that has already been submitted.
Skipped
Skipped means the Event ID already exists, but the Wholechain account is not configured to allow events to be updated.
For example:
SHIP-001 already exists
↓
SHIP-001 submitted again
↓
Event Updates = Disabled
↓
Existing event remains unchanged
↓
status: Skipped
A skipped event does not mean that the API failed to process the request.
It means Wholechain recognized that the event already exists and did not replace or update the existing event.
For example:
{
"externalEventId": "SHIP-001",
"type": "Ship",
"status": "Skipped"
}
If you expected the existing event to change but receive Skipped, check whether event updates are enabled for your Wholechain account.
Updated
Updated means the Event ID already exists and Wholechain has updated the existing event based on the values provided in the new payload.
For example:
Original Event
Event ID: RECEIVE-001
Quantity: 50 kg
Updated Payload
Event ID: RECEIVE-001
Quantity: 100 kg
If updates are enabled:
RECEIVE-001 already exists
↓
New payload submitted
↓
Event Updates = Enabled
↓
Existing event updated
↓
status: Updated
The response would indicate:
{
"externalEventId": "RECEIVE-001",
"type": "Receive",
"status": "Updated"
}
The same Event ID is important because you are modifying the existing event rather than creating another event.
Event Status Flow
The event response can therefore be understood as:
Does this Event ID already exist?
│
┌────┴────┐
│ │
NO YES
│ │
↓ ↓
Created Are updates enabled?
│
┌────┴────┐
│ │
NO YES
│ │
↓ ↓
Skipped Updated
Payload-Level Event Failure
When submitting multiple events in a single request, the payload is processed as a single transaction.
If any one event in the payload contains an error that prevents it from being processed, the entire payload will fail.
This means that Wholechain will not process the remaining valid events independently.
For example:
Payload
│
├── Commission Event ✅ Valid
├── Receive Event ✅ Valid
├── Transform Event ❌ Error
└── Ship Event ✅ Valid
Because the Transform event contains an error:
Transform Event
↓
Error
↓
Entire Payload Fails
The valid Commission, Receive, and Ship events will not be processed separately.
Important
When sending multiple events in the same payload:
- Every event must be valid for the payload to process successfully.
- One event-level error can cause the entire request to fail.
- Do not assume that valid events within a failed payload were created.
- Review the returned
errorsandvalidationsbefore resubmitting the payload. - Correct the event causing the error and resubmit the payload.
New locations, trade partners and products supplied through Details are created before the events are validated, and are kept even if the payload fails. When you resubmit the corrected payload they will be returned as Skipped.
This is especially important when submitting a sequence of dependent events such as:
Commission
↓
Receive
↓
Transform
↓
Ship
If one event in the sequence fails validation or processing, the full payload must be corrected before the sequence can be successfully processed.
Product Instance Status
Inside each event, the response may also contain productInstances.
For example:
"productInstances": [
{
"quantity": 75,
"lotSerial": "LOT-SHIP-2025071501",
"status": "Created",
"id": "01a0d87d-e737-784e-be4c-90eaf85d37a8",
"name": "Atlantic Salmon Fillet 10lb",
"urn": "urn:gdst:wholechain.com:product:lot:class:raindropsolutions.atlanticsalmonfillet10lb.lot-ship-2025071501"
}
]
A product instance represents the specific product and lot involved in that event.
Useful fields include:
| Field | Description |
|---|---|
quantity | Quantity associated with that product instance in the event. |
lotSerial | Lot or serial number. |
status | Processing status for the product instance. |
id | Wholechain-generated ID for the product instance. |
name | Product name. |
urn | Wholechain URN identifying the product instance. |
The product instance status should be reviewed alongside the overall event status.
Product-Level Response
If product information is submitted as part of the event request, the top-level products array tells you what Wholechain did with those product records.
For example:
"products": [
{
"id": "01a0d877-7719-720e-8fd8-224e3fec0602",
"status": "Skipped"
}
]
The same general status concept applies:
| Status | Meaning |
|---|---|
Created | A new product was created. |
Skipped | The product already existed and was not changed. |
Updated | The existing product was updated. |
For example:
Event: Created
Product: Skipped
is completely possible.
This means the event itself was new, but the product referenced by the event already existed in Wholechain and did not need to be created again.
Location-Level Response
The top-level locations array works in the same way.
For example:
"locations": [
{
"id": "01a0d877-76de-7e96-ac8c-962a914952bf",
"status": "Skipped"
}
]
The status describes what happened to the location record:
| Status | Meaning |
|---|---|
Created | The location was created as part of processing the request. |
Skipped | The location already existed and was not changed. |
Updated | The existing location was updated. |
It is therefore normal to receive a response such as:
Event
status: Created
Location
status: Skipped
Product
status: Skipped
This means:
Product already exists ──────→ Skipped
│
Location already exists ─────→ Skipped
│
↓
New Event created
│
↓
Created
Wholechain does not need to recreate the same product and location every time they are referenced by a new event.
Example: New Event Using Existing Product and Location
Consider this response:
{
"message": "Events processed successfully",
"result": [
{
"externalEventId": "commission_001",
"type": "Commission",
"status": "Created"
}
],
"locations": [
{
"id": "01a0d877-76de-7e96-ac8c-962a914952bf",
"status": "Skipped"
}
],
"products": [
{
"id": "01a0d877-7719-720e-8fd8-224e3fec0602",
"status": "Skipped"
}
],
"errors": [],
"validations": []
}
This means:
Product
Already Exists
↓
Skipped
Location
Already Exists
↓
Skipped
Commission Event
Did Not Exist
↓
Created
The event can therefore be successfully created even though the related product and location are returned as Skipped.
Direct Ship Fallback
Ship events can be submitted with Direct Ship enabled.
Normally, Wholechain expects the inventory being shipped to exist at the shipping location before the Ship event occurs.
For example:
Available Inventory
LOT-001
75 kg
↓
Ship
75 kg
↓
Normal Shipment
However, if Direct Ship is enabled and Wholechain cannot find the required inventory, Wholechain can still create the shipment using a Direct Ship fallback.
For example:
Ship requests:
LOT-001
75 kg
↓
Wholechain searches inventory
↓
Inventory not found
↓
Direct Ship = true
↓
Direct Ship Fallback
↓
Ship event still created
When this occurs, the response includes the directShipFallback object.
Direct Ship Fallback Response
For example:
"directShipFallback": {
"reason": "MissingInventory",
"missingLots": [
{
"lotSerial": "LOT-SHIP-2025071501",
"productIdentifier": "prod_atlantic_salmon_fillet_10lb",
"requestedQuantity": 75,
"missingQuantity": 75
}
]
}
This is important.
The Ship event may still return:
"status": "Created"
but the directShipFallback tells you that Wholechain could not find the normal inventory required for the shipment.
The event was created because Direct Ship allowed Wholechain to continue despite that missing inventory.
Understanding MissingInventory
When:
"reason": "MissingInventory"
is returned, Wholechain could not find all of the inventory requested by the Ship event.
The missingLots array explains exactly what was missing.
For example:
{
"lotSerial": "LOT-SHIP-2025071501",
"productIdentifier": "prod_atlantic_salmon_fillet_10lb",
"requestedQuantity": 75,
"missingQuantity": 75
}
means:
| Field | Value |
|---|---|
| Lot requested | LOT-SHIP-2025071501 |
| Product requested | prod_atlantic_salmon_fillet_10lb |
| Quantity requested | 75 |
| Quantity missing | 75 |
In this example, none of the requested 75 units could be found in available inventory.
Wholechain therefore used the Direct Ship fallback.
Direct Ship Fallback Does Not Mean the Event Failed
This distinction is important.
A response such as:
{
"status": "Created",
"directShipFallback": {
"reason": "MissingInventory"
}
}
means:
Event processing
↓
Inventory not found
↓
Direct Ship enabled
↓
Fallback used
↓
Ship event created successfully
It does not mean:
Ship event failed
The Ship was created, but it was created using Direct Ship because the expected inventory could not be found.
You should therefore review directShipFallback whenever processing Ship responses.
No Direct Ship Fallback
If normal inventory was found, or the event does not require Direct Ship fallback processing, the response may contain:
"directShipFallback": null
For example:
{
"externalEventId": "SHIP-001",
"type": "Ship",
"status": "Created",
"directShipFallback": null
}
This means a Direct Ship fallback was not used.
Complete Direct Ship Example
{
"message": "Events processed successfully",
"result": [
{
"id": "01a0d87d-e737-72ec-adbf-02af9fc236ae",
"externalEventId": "ship-evt-2025071501",
"type": "Ship",
"status": "Created",
"eventDate": "2025-07-15T09:30:00+00:00",
"productInstances": [
{
"quantity": 75,
"lotSerial": "LOT-SHIP-2025071501",
"status": "Created",
"id": "01a0d87d-e737-784e-be4c-90eaf85d37a8",
"name": "Atlantic Salmon Fillet 10lb",
"urn": "urn:gdst:wholechain.com:product:lot:class:raindropsolutions.atlanticsalmonfillet10lb.lot-ship-2025071501"
}
],
"containers": [],
"directShipFallback": {
"reason": "MissingInventory",
"missingLots": [
{
"lotSerial": "LOT-SHIP-2025071501",
"productIdentifier": "prod_atlantic_salmon_fillet_10lb",
"requestedQuantity": 75,
"missingQuantity": 75
}
]
},
"externalShipmentFailure": null
}
],
"locations": [],
"products": [],
"errors": [],
"validations": []
}
This response can be interpreted as:
Ship Event
SHIP-EVT-2025071501
│
├── Event Status: Created
│
├── Requested Quantity: 75
│
├── Inventory Found: No
│
├── Missing Quantity: 75
│
└── Direct Ship Fallback: Used
The event was successfully created, but the response also warns you that the normal inventory was unavailable.
Errors
The response contains an errors array:
"errors": []
If the array is empty, no event-processing errors were returned in this section of the response.
If errors are present, review them before considering the entire request successfully processed as intended.
Validations
The response also contains a validations array:
"validations": []
Validation information returned during processing will appear here.
An empty array means no validation messages were returned in this section.
externalShipmentFailure
Event responses may also include:
"externalShipmentFailure": null
This field is separate from directShipFallback.
If it is null, no external shipment failure is being reported for that event.
If information is returned in this field, review it separately from the event's general processing status.
Reading a Response Correctly
Do not only check:
"message": "Events processed successfully"
Instead, review the response in this order:
1. Event Status
Check:
"status"
Determine whether the event was:
Created
Skipped
Updated
2. Product Instances
Confirm:
- Lot or serial
- Quantity
- Product name
- Product instance status
3. Direct Ship Fallback
For Ship events, check:
"directShipFallback"
If it is not null, review why fallback processing occurred and which lots or quantities were missing.
4. Locations
Review whether locations were:
Created
Skipped
Updated
5. Products
Review whether products were:
Created
Skipped
Updated
6. Errors
Check whether:
"errors": []
contains any returned errors.
7. Validations
Check whether:
"validations": []
contains any validation information.
Example Response Summary
A response such as:
Event: Created
Product Instance: Created
Location: Skipped
Product: Skipped
Direct Ship Fallback: MissingInventory
Errors: None
Validations: None
means:
Existing Product ─────────────→ Reused
Existing Location ────────────→ Reused
│
↓
New Ship Event
│
Inventory Missing
│
↓
Direct Ship Fallback
│
↓
Event Created
This is a successfully created Ship event, but the response also provides important information that the inventory was not available and Direct Ship fallback processing was required.
Important Notes
- Always review the individual event
status; do not rely only on the top-level response message. Createdmeans the Event ID did not previously exist.Skippedmeans the Event ID already existed and updates were not applied.Updatedmeans the existing event was updated using the newly submitted payload.- Products and locations have their own statuses independent of the event status.
- A new event can reference an existing product and location, so
Event: Created,Product: Skipped, andLocation: Skippedis a normal response. - Review
productInstancesto confirm the lot, quantity, product, and product-instance processing result. - For Ship events, always check
directShipFallback. - A populated
directShipFallbackmeans the shipment was processed using fallback behavior because the expected inventory could not be found. MissingInventoryidentifies the product, lot, requested quantity, and quantity that Wholechain could not find.- A Direct Ship fallback does not by itself mean the Ship event failed.
directShipFallback: nullmeans no Direct Ship fallback is being reported.- Always review the
errorsandvalidationsarrays before considering processing complete.