Ship a Lot
Ship a Lot. The request example includes all fields documented for this event, including optional fields.
curl -X POST "https://connect.wholechain.com/Integration/Events" \
-H "Content-Type: application/json" \
-H "X-API-KEY: example_string" \
-d '{
"Events": [
{
"$type": "ship",
"ShipFromLocation": {
"Id": "warehouse_001"
},
"ShipToLocation": {
"Id": "customer_location_001",
"Details": {
"TradePartner": {
"Id": "buyer_001",
"Name": "Example Buyer",
"ConnectionType": "BUYER",
"Duns": "123456789"
},
"Name": "Customer Distribution Centre",
"Gln": "9506000140447",
"Extension": "CustomerExtension",
"ContactInformation": {
"Name": "Customer Contact",
"Phone": "+1234567892",
"Email": "customer@example.com"
},
"Address": {
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"AddressLine1": "789 Customer Avenue",
"AddressLine2": "Building 2",
"PostalCode": "8003",
"GeoCoordinates": {
"Latitude": -33.926,
"Longitude": 18.426
}
}
}
},
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "lot_001",
"Product": {
"Id": "product_001"
}
}
],
"DirectShip": true,
"Id": "ship_lot_001",
"PurchaseOrder": "PO-12345",
"InvoiceNumber": "INV-12345",
"EventTime": "2024-03-30T16:00:00",
"EventTimeZone": "-05:00",
"CustomProperties": [
{
"Name": "quality_grade",
"Namespace": "custom",
"Value": "A"
}
],
"CertificationList": [
{
"Type": "urn:gdst:certType:harvestCoC",
"Standard": "MSC Chain of Custody",
"Agency": "MSC",
"Value": "YES",
"Identification": "MSC-C-12345"
}
]
}
]
}'
import requests
import json
url = "https://connect.wholechain.com/Integration/Events"
headers = {
"Content-Type": "application/json",
"X-API-KEY": "example_string"
}
data = {
"Events": [
{
"$type": "ship",
"ShipFromLocation": {
"Id": "warehouse_001"
},
"ShipToLocation": {
"Id": "customer_location_001",
"Details": {
"TradePartner": {
"Id": "buyer_001",
"Name": "Example Buyer",
"ConnectionType": "BUYER",
"Duns": "123456789"
},
"Name": "Customer Distribution Centre",
"Gln": "9506000140447",
"Extension": "CustomerExtension",
"ContactInformation": {
"Name": "Customer Contact",
"Phone": "+1234567892",
"Email": "customer@example.com"
},
"Address": {
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"AddressLine1": "789 Customer Avenue",
"AddressLine2": "Building 2",
"PostalCode": "8003",
"GeoCoordinates": {
"Latitude": -33.926,
"Longitude": 18.426
}
}
}
},
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "lot_001",
"Product": {
"Id": "product_001"
}
}
],
"DirectShip": true,
"Id": "ship_lot_001",
"PurchaseOrder": "PO-12345",
"InvoiceNumber": "INV-12345",
"EventTime": "2024-03-30T16:00:00",
"EventTimeZone": "-05:00",
"CustomProperties": [
{
"Name": "quality_grade",
"Namespace": "custom",
"Value": "A"
}
],
"CertificationList": [
{
"Type": "urn:gdst:certType:harvestCoC",
"Standard": "MSC Chain of Custody",
"Agency": "MSC",
"Value": "YES",
"Identification": "MSC-C-12345"
}
]
}
]
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://connect.wholechain.com/Integration/Events", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "example_string"
},
body: JSON.stringify({
"Events": [
{
"$type": "ship",
"ShipFromLocation": {
"Id": "warehouse_001"
},
"ShipToLocation": {
"Id": "customer_location_001",
"Details": {
"TradePartner": {
"Id": "buyer_001",
"Name": "Example Buyer",
"ConnectionType": "BUYER",
"Duns": "123456789"
},
"Name": "Customer Distribution Centre",
"Gln": "9506000140447",
"Extension": "CustomerExtension",
"ContactInformation": {
"Name": "Customer Contact",
"Phone": "+1234567892",
"Email": "customer@example.com"
},
"Address": {
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"AddressLine1": "789 Customer Avenue",
"AddressLine2": "Building 2",
"PostalCode": "8003",
"GeoCoordinates": {
"Latitude": -33.926,
"Longitude": 18.426
}
}
}
},
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "lot_001",
"Product": {
"Id": "product_001"
}
}
],
"DirectShip": true,
"Id": "ship_lot_001",
"PurchaseOrder": "PO-12345",
"InvoiceNumber": "INV-12345",
"EventTime": "2024-03-30T16:00:00",
"EventTimeZone": "-05:00",
"CustomProperties": [
{
"Name": "quality_grade",
"Namespace": "custom",
"Value": "A"
}
],
"CertificationList": [
{
"Type": "urn:gdst:certType:harvestCoC",
"Standard": "MSC Chain of Custody",
"Agency": "MSC",
"Value": "YES",
"Identification": "MSC-C-12345"
}
]
}
]
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"Events": [
{
"$type": "ship",
"ShipFromLocation": {
"Id": "warehouse_001"
},
"ShipToLocation": {
"Id": "customer_location_001",
"Details": {
"TradePartner": {
"Id": "buyer_001",
"Name": "Example Buyer",
"ConnectionType": "BUYER",
"Duns": "123456789"
},
"Name": "Customer Distribution Centre",
"Gln": "9506000140447",
"Extension": "CustomerExtension",
"ContactInformation": {
"Name": "Customer Contact",
"Phone": "+1234567892",
"Email": "customer@example.com"
},
"Address": {
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"AddressLine1": "789 Customer Avenue",
"AddressLine2": "Building 2",
"PostalCode": "8003",
"GeoCoordinates": {
"Latitude": -33.926,
"Longitude": 18.426
}
}
}
},
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "lot_001",
"Product": {
"Id": "product_001"
}
}
],
"DirectShip": true,
"Id": "ship_lot_001",
"PurchaseOrder": "PO-12345",
"InvoiceNumber": "INV-12345",
"EventTime": "2024-03-30T16:00:00",
"EventTimeZone": "-05:00",
"CustomProperties": [
{
"Name": "quality_grade",
"Namespace": "custom",
"Value": "A"
}
],
"CertificationList": [
{
"Type": "urn:gdst:certType:harvestCoC",
"Standard": "MSC Chain of Custody",
"Agency": "MSC",
"Value": "YES",
"Identification": "MSC-C-12345"
}
]
}
]
}`)
req, err := http.NewRequest("POST", "https://connect.wholechain.com/Integration/Events", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-KEY", "example_string")
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/Events')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['X-API-KEY'] = 'example_string'
request.body = '{
"Events": [
{
"$type": "ship",
"ShipFromLocation": {
"Id": "warehouse_001"
},
"ShipToLocation": {
"Id": "customer_location_001",
"Details": {
"TradePartner": {
"Id": "buyer_001",
"Name": "Example Buyer",
"ConnectionType": "BUYER",
"Duns": "123456789"
},
"Name": "Customer Distribution Centre",
"Gln": "9506000140447",
"Extension": "CustomerExtension",
"ContactInformation": {
"Name": "Customer Contact",
"Phone": "+1234567892",
"Email": "customer@example.com"
},
"Address": {
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"AddressLine1": "789 Customer Avenue",
"AddressLine2": "Building 2",
"PostalCode": "8003",
"GeoCoordinates": {
"Latitude": -33.926,
"Longitude": 18.426
}
}
}
},
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "lot_001",
"Product": {
"Id": "product_001"
}
}
],
"DirectShip": true,
"Id": "ship_lot_001",
"PurchaseOrder": "PO-12345",
"InvoiceNumber": "INV-12345",
"EventTime": "2024-03-30T16:00:00",
"EventTimeZone": "-05:00",
"CustomProperties": [
{
"Name": "quality_grade",
"Namespace": "custom",
"Value": "A"
}
],
"CertificationList": [
{
"Type": "urn:gdst:certType:harvestCoC",
"Standard": "MSC Chain of Custody",
"Agency": "MSC",
"Value": "YES",
"Identification": "MSC-C-12345"
}
]
}
]
}'
response = http.request(request)
puts response.body
{
"message": "Events processed successfully",
"result": [
{
"id": "01a0d877-7871-79a5-a8c8-a2f45673633d",
"externalEventId": "ship_lot_001",
"type": "Ship",
"status": "Created",
"eventDate": "2024-03-30T16:00:00+00:00",
"productInstances": [
{
"quantity": 190.75,
"lotSerial": "lot_001",
"status": "Created",
"id": "01a0d877-7871-7426-b365-3a587ad4f893",
"name": "Raw Goods",
"urn": "urn:gdst:wholechain.com:product:lot:class:raindropsolutions.rawgoods-1.lot_001"
}
],
"containers": [],
"directShipFallback": null,
"externalShipmentFailure": null
}
],
"locations": [
{
"id": "01a0d877-76de-7e96-ac8c-962a914952bf",
"status": "Created"
}
],
"products": [
{
"id": "01a0d877-7719-720e-8fd8-224e3fec0602",
"status": "Created"
}
],
"errors": [],
"validations": []
}
/Integration/Events
Target server for requests. Edit to use your own host.
The media type of the request body
API key used to authenticate the request.
Required. events.
Request Preview
Response
Response will appear here after sending the request
Responses
Optional. message.
Optional. result.
Optional. locations.
Optional. products.
Optional. errors.
Optional. validations.
Introduction
A Ship event represents a product lot moving from one Location to another.
A Ship event can represent either:
- Internal movement — for example, shipping a lot from one warehouse to another warehouse within your business.
- External movement — for example, shipping a lot from your warehouse to a customer, buyer, or other external Trade Partner.
The product itself does not change. The event records the movement of an existing Product and Lot from the Ship From Location to the Ship To Location.
The purpose of this endpoint is to create a Ship event for a lot in Wholechain.


Creating a Ship Event
To ship a lot, submit an event payload containing:
- The event information
- The Location the lot is shipping from
- The Location the lot is shipping to
- The Product
- The Lot Number
- The quantity being shipped
- Whether Direct Ship should be enabled
Wholechain uses the Product ID and Lot Number to identify the inventory being shipped from the Ship From Location.
Use the Required column in the tables below to determine which fields must be provided.
Request Body Parameters
Event Object
| Column Name | Data Type | Description | Required |
|---|---|---|---|
Id | STRING | Unique identifier for the Ship event. | Yes |
PurchaseOrder | STRING | Purchase order associated with the shipment. | No |
InvoiceNumber | STRING | Invoice number associated with the shipment. | No |
DirectShip | BOOLEAN | Optional. Default false. When true, the Ship is recorded even if the inventory cannot be found (Direct Ship fallback). | No |
EventTime | DATETIME | Local date and time when the event occurred, without a UTC offset, for example 2024-03-30T13:00:00. The time zone is taken from EventTimeZone. Any offset included in this value is ignored. | Yes |
EventTimeZone | STRING | Optional. Time zone of the event as a UTC offset in ±HH:MM format, for example -05:00. If omitted, the account's default time zone (selected when the account was created) is used. | No |
Ship From Location
Every Ship event must identify the Location where the lot is shipping from.
| Column Name | Data Type | Description | Required |
|---|---|---|---|
ShipFromLocation.Id | STRING | Unique identifier for the Location the lot is shipping from. | Yes |
Example:
"ShipFromLocation": {
"Id": "warehouse_001"
}
The Ship From Location represents the Location where Wholechain expects the Product and Lot inventory to exist.
Ship To Location
Every Ship event must identify the Location where the lot is shipping to.
This can be:
- Another Location within your own business
- A Location belonging to an external Trade Partner
| Column Name | Data Type | Description | Required |
|---|---|---|---|
ShipToLocation.Id | STRING | Unique identifier for the destination Location. | Yes |
ShipToLocation.Details | OBJECT | Information used to create the destination Location if it does not already exist. | Yes if Location does not exist |
Existing Ship To Location
If the destination Location already exists in Wholechain, only its Id needs to be supplied.
"ShipToLocation": {
"Id": "warehouse_002"
}
This could represent another warehouse within your business or an existing external customer Location.
Creating the Ship To Location
If the supplied ShipToLocation.Id does not already exist in Wholechain, include the Details object.
Wholechain will use this information to create the destination Location before processing the Ship event.
"ShipToLocation": {
"Id": "customer_location_001",
"Details": {
"TradePartner": {
"Id": "customer_123",
"Name": "Example Customer",
"ConnectionType": "BUYER"
},
"Name": "Customer Distribution Centre",
"Address": {
"Country": "South Africa",
"AddressLine1": "123 Main Street"
}
}
}
The same structure can be used when the destination is another Location within your own business.
Location Details Object
Trade Partner
Every Location belongs to a Trade Partner.
| Column Name | Data Type | Description | Required |
|---|---|---|---|
TradePartner | OBJECT | Trade Partner associated with the destination Location. | Yes |
TradePartner.Id | STRING | Unique identifier for the Trade Partner. | Yes |
TradePartner.Name | STRING | Name of the Trade Partner. | Yes |
TradePartner.ConnectionType | STRING | Relationship to the Trade Partner, such as SELF, SUPPLIER, BUYER, or OTHER. | Yes |
TradePartner.Duns | STRING | DUNS number associated with the Trade Partner. | No |
If the Trade Partner already exists in Wholechain, its existing ID can be referenced.
If it does not exist, Wholechain will create the Trade Partner using the supplied information before creating the Location.
Internal Shipment
For a shipment between Locations within your own business, the destination Location can be associated with your own Trade Partner using:
"ConnectionType": "SELF"
External Shipment
For a shipment to an external customer or buyer, the destination Location can be associated with that Trade Partner using:
"ConnectionType": "BUYER"
Location Information
| Column Name | Data Type | Description | Required |
|---|---|---|---|
Name | STRING | Name of the Location. | Yes if creating new |
Gln | STRING | Global Location Number of the Location. | No |
Extension | STRING | Additional Location information. | No |
ContactInformation | OBJECT | Contact information associated with the Location. | No |
ContactInformation.Name | STRING | Name of the contact person. | No |
ContactInformation.Phone | STRING | Phone number of the contact person. | No |
ContactInformation.Email | STRING | Email address of the contact person. | No |
Address Object
| Column Name | Data Type | Description | Required |
|---|---|---|---|
Address | OBJECT | Address information for the Location. | Yes if creating new |
Address.City | STRING | City where the Location is situated. | No |
Address.State | STRING | State or region where the Location is situated. | No |
Address.Country | STRING | Country of the Location. | Yes if creating new |
Address.AddressLine1 | STRING | Primary address line of the Location. | Yes if creating new |
Address.AddressLine2 | STRING | Secondary address line of the Location. | No |
Address.PostalCode | STRING | Postal code of the Location. | No |
Address.GeoCoordinates | OBJECT | Geographical coordinates of the Location. | No |
Address.GeoCoordinates.Latitude | DECIMAL | Latitude of the Location. | No |
Address.GeoCoordinates.Longitude | DECIMAL | Longitude of the Location. | No |
Product Instance Object
The ProductInstances array identifies the Product, Lot Number, and quantity being shipped.
| Column Name | Data Type | Description | Required |
|---|---|---|---|
Quantity | DECIMAL | Quantity of the lot being shipped. | Yes |
LotSerial | STRING | Lot Number of the product being shipped. | Yes |
Product | OBJECT | Product associated with the lot. | Yes |
Product.Id | STRING | Unique identifier for the Product. | Yes |
Example:
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "LOT-001",
"Product": {
"Id": "product_001"
}
}
]
The combination of Product.Id and LotSerial identifies the inventory Wholechain should ship from the Ship From Location.
Direct Ship
The DirectShip field determines what Wholechain should do if the Product and Lot inventory referenced in the Ship event cannot be found at the Ship From Location.
It is a boolean field and can be set to either:
"DirectShip": true
or:
"DirectShip": false
DirectShip = false
When:
"DirectShip": false
Wholechain expects the Product and Lot inventory to exist at the Ship From Location before the shipment can be processed.
If the inventory cannot be found, the Ship event will not be created.
This is used when you want Wholechain inventory to be validated before allowing the shipment to proceed.
DirectShip = true
When:
"DirectShip": true
Wholechain will first attempt to find the Product and Lot inventory at the Ship From Location.
If the inventory exists, the shipment is processed normally.
If the inventory cannot be found, Wholechain will still create the Ship event.
This acts as a fallback for situations where the physical shipment is valid, but an earlier data issue prevented the inventory from successfully reaching the expected Location in Wholechain.
For example:
Previous Event
↓
Data issue prevents inventory
from appearing in Wholechain
↓
Physical product still exists
and must be shipped
↓
DirectShip = true
↓
Ship event is still created
This allows you to continue sending valid shipment information to Wholechain even when there is a gap in the upstream digital traceability chain.
Direct Ship Behavior
| Inventory Found? | DirectShip | Result |
|---|---|---|
| Yes | false | Shipment is created normally. |
| Yes | true | Shipment is created normally. |
| No | false | Shipment is not created. |
| No | true | Shipment is still created using Direct Ship fallback. |
Direct Ship should therefore be used when you want the shipment to continue even if Wholechain cannot locate the expected upstream inventory.
Shipping Multiple Lots
Multiple lots can be shipped within the same Ship event by adding additional objects to the ProductInstances array.
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "LOT-001",
"Product": {
"Id": "product_001"
}
},
{
"Quantity": 75,
"LotSerial": "LOT-002",
"Product": {
"Id": "product_002"
}
}
]
Each Product Instance identifies a specific Product, Lot Number, and quantity being shipped.
Duplicate Lots
Do not send the same Product and Lot Number multiple times within the same Ship event.
If multiple records represent the same Product and Lot Number, combine their quantities before sending the event.
Instead of:
"ProductInstances": [
{
"Quantity": 100,
"LotSerial": "LOT-001",
"Product": {
"Id": "product_001"
}
},
{
"Quantity": 50,
"LotSerial": "LOT-001",
"Product": {
"Id": "product_001"
}
}
]
Send:
"ProductInstances": [
{
"Quantity": 150,
"LotSerial": "LOT-001",
"Product": {
"Id": "product_001"
}
}
]
Example Ship Event Payload
The example below shows a lot being shipped from a warehouse to an external customer Location.
The same payload structure can be used when shipping between two Locations within your own business.
In this example, DirectShip is set to true, meaning Wholechain will still create the Ship event if the requested inventory cannot be found.
{
"Events": [
{
"$type": "ship",
"ShipFromLocation": {
"Id": "warehouse_001"
},
"ShipToLocation": {
"Id": "customer_location_001",
"Details": {
"TradePartner": {
"Id": "customer_123",
"Name": "Example Customer",
"ConnectionType": "BUYER",
"Duns": "123456789"
},
"Name": "Customer Distribution Centre",
"Gln": "9506000140445",
"ContactInformation": {
"Name": "Contact Name",
"Phone": "+1234567890",
"Email": "contact@example.com"
},
"Address": {
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"AddressLine1": "123 Main Street",
"PostalCode": "8001",
"GeoCoordinates": {
"Latitude": -33.9249,
"Longitude": 18.4241
}
}
}
},
"ProductInstances": [
{
"Quantity": 190.75,
"LotSerial": "LOT-001",
"Product": {
"Id": "product_001"
}
}
],
"DirectShip": true,
"Id": "SHIP-0004",
"PurchaseOrder": "1990091",
"InvoiceNumber": "12314154",
"EventTime": "2024-03-30T16:00:00",
"EventTimeZone": "-05:00"
}
]
}
How Wholechain Processes the Payload
When a Ship event is submitted, Wholechain:
- Identifies the Ship From Location.
- Identifies the Ship To Location.
- Creates the Ship To Location and Trade Partner if they do not already exist and the required
Detailsare supplied. - Identifies the Product and Lot Number using
Product.IdandLotSerial. - Attempts to find the requested inventory at the Ship From Location.
- If the inventory is found, processes the shipment normally.
- If the inventory is not found:
DirectShip: false→ the Ship event is not created.DirectShip: true→ the Ship event is still created using Direct Ship fallback.
- Creates the Ship event and records the movement to the Ship To Location.
The Ship event represents the movement of a lot, whether the destination is internal or external.
Direct Ship provides a fallback when the physical shipment is valid but the expected upstream inventory is missing from Wholechain.
Custom Properties and Certifications
A Ship event can also contain Custom Properties and Certifications when additional traceability information needs to be recorded.
The full example above includes CustomProperties and CertificationList; see the pages below for details.
For information about how to include them in your payload, see:
- Custom Properties: Custom Properties
- Certifications: Certifications
TLC and Additional Fields
Additional traceability fields may also be included where required for a particular implementation.
Wholechain supports TLC Source information using either:
- A reference identifier
- Full TLC Source Location details
For more information about TLC Source and other supported additional fields, see: