EventsUnderstanding Event Responses

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:

StatusMeaning
CreatedThe Event ID did not previously exist and a new event was created.
SkippedThe Event ID already exists, but event updates are not enabled for the Wholechain account. The existing event is therefore left unchanged.
UpdatedThe 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 errors and validations before 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:

FieldDescription
quantityQuantity associated with that product instance in the event.
lotSerialLot or serial number.
statusProcessing status for the product instance.
idWholechain-generated ID for the product instance.
nameProduct name.
urnWholechain 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:

StatusMeaning
CreatedA new product was created.
SkippedThe product already existed and was not changed.
UpdatedThe 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:

StatusMeaning
CreatedThe location was created as part of processing the request.
SkippedThe location already existed and was not changed.
UpdatedThe 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:

FieldValue
Lot requestedLOT-SHIP-2025071501
Product requestedprod_atlantic_salmon_fillet_10lb
Quantity requested75
Quantity missing75

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.
  • Created means the Event ID did not previously exist.
  • Skipped means the Event ID already existed and updates were not applied.
  • Updated means 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, and Location: Skipped is a normal response.
  • Review productInstances to confirm the lot, quantity, product, and product-instance processing result.
  • For Ship events, always check directShipFallback.
  • A populated directShipFallback means the shipment was processed using fallback behavior because the expected inventory could not be found.
  • MissingInventory identifies 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: null means no Direct Ship fallback is being reported.
  • Always review the errors and validations arrays before considering processing complete.