Transform
Endpoint URL
https://connect.wholechain.com/Integration/JSON
Sandbox URL
https://connect-sandbox.wholechain.com/Integration/JSON
Method
POST
Introduction
A Transform event describes an activity that irreversibly changes a product, transforming it into a new, traceable output product with a new Primary ID (i.e. a new serial number or lot number). It could be that raw materials are combined, cut or melted to make a new product, or that a product is packaged for consumption.
How it works
- A Wholechain user selects the input item(s) they want to transform from their current inventory, and is prompted to specify details about the output product.
- The user can enter the output product details manually or via CSV upload for multiple items.
- The new product appears in the Current Inventory of that product page. Users can also use the "+ product" tab in the event drawer to transform multiple inputs into multiple output products.
- This event can also be performed through the API
Practical Examples
- At a seafood processor, an input lot of whole sockeye salmon is processed into three distinct production lots of packaged sockeye salmon fillets.
- Traceable harvests from multiple fishing vessels are irreversibly combined into one container of whole sockeye salmon upon landing.
- At a pasta factory, workers mix flour, egg and water input products to create 4 differently-shaped pasta output products.
Authentication
The API uses an API key (X-API-KEY) to authenticate requests. Each user has a unique API key that controls access to event details tied to their company. To understand where this can be found, please visit the Authentication page.
Request Headers:
Header | Description | Example Value |
---|---|---|
X-API-KEY |
Your API key | YOUR_API_KEY_HERE |
Content-Type |
Content type of the request | application/json |
accept |
Response content type | */* |
Request Body Parameters:
Location Object
Column Name | Data Type | Description |
---|---|---|
Urn |
STRING | Unique identifier for the location. |
TradePartnerUrn |
STRING | Trade Partner URN associated with the location. |
Name |
STRING | Name of the location. |
Gln |
STRING | Global Location Number (GLN), if available. |
City |
STRING | City where the location is based. |
State |
STRING | State or province. |
Country |
STRING | Country. |
AddressLine1 |
STRING | First line of the address. |
AddressLine2 |
STRING | Second line of the address (optional). |
PostalCode |
STRING | Postal or ZIP code. |
Latitude |
FLOAT | Geographic latitude of the location. |
Longitude |
FLOAT | Geographic longitude of the location. |
TradePartner Object
Column Name | Data Type | Description |
---|---|---|
Urn |
STRING | Unique identifier for the trade partner. |
TradePartnerId |
STRING | Unique ID for the trade partner (optional). |
Name |
STRING | Name of the trade partner. |
Pgln |
STRING | Party GLN (Global Location Number). |
ConnectionType |
STRING | Type of connection (e.g., SELF). |
ProductInstances Object
Column Name | Data Type | Description |
---|---|---|
Quantity |
FLOAT | Quantity of the product in this instance. |
LotSerial |
STRING | Lot or serial number of the product. |
Urn |
STRING | Unique identifier for the product instance. |
UOM |
STRING | Unit of measurement (e.g., Lbs). |
Gtin |
STRING | Global Trade Item Number (optional). |
ParentProductUrn |
STRING | URN of the parent product. |
ParentProductName |
STRING | Name of the parent product. |
SimpleUOM |
STRING | Simplified unit of measurement. |
SharingPolicy |
STRING | Product sharing policy (e.g., Open). |
ProductIdentifierType |
STRING | Identifier type (e.g., Lot). |
ProductMasterData Object
Column Name | Data Type | Description |
---|---|---|
ParentProductUrn |
STRING | URN of the parent product this data is associated with. |
Name |
STRING | Name of the product attribute. |
Namespace |
STRING | Namespace of the attribute (e.g., cbvmda ). |
Value |
STRING | Value of the product attribute. |
ElementId |
STRING | Element ID for the attribute. |
Event Object
Column Name | Data Type | Description |
---|---|---|
ExternalEventId |
STRING | This must be different for every API call |
PurchaseOrder |
STRING | Purchase order number. |
InvoiceNumber |
STRING | Invoice number associated with the event. |
BizStep |
STRING | Business step identifier. |
Disposition |
STRING | Disposition of the product in the event. |
EventTime |
DATETIME | Timestamp for when the event occurred. |
EventTimeZone |
STRING | Time zone offset for the event. |
RecordTime |
DATETIME | Timestamp for when the event was recorded. |
CustomProperties Object
Column Name | Data Type | Description |
---|---|---|
EventId |
STRING | ID of the event this property is associated with. |
Name |
STRING | Name of the custom property. |
Namespace |
STRING | Namespace of the property. |
Value |
STRING | Value of the custom property. |
PropertyLocation |
STRING | Location of the property (e.g., ILMD). |
CertificationList Object
Column Name | Data Type | Description |
---|---|---|
EventId |
STRING | ID of the event this certification is linked to. |
CertificationType |
STRING | Type of certification (e.g., harvestCoC). |
CertificationStandard |
STRING | Certification standard (e.g., MSC Chain of Custody). |
CertificationAgency |
STRING | Agency providing the certification. |
CertificationValue |
STRING | Certification value. |
CertificationIdentification |
STRING | Certification identification number or code. |
Example Requests
import requests
url = 'https://connect.wholechain.com/Integration/JSON'
headers = {
'accept': '*/*',
'X-API-KEY': '32459f03-6de9-44cc-a101-792934d35c6c',
'Content-Type': 'application/json'
}
data = {
"Events": [
{
"$type": "transform",
"Location": {
"Urn": "urn:gdst:wholechain.com:location:loc:brunosfishimports.mainwarehouse",
"TradePartnerUrn": "urn:gdst:wholechain.com:party:brunosfishimports.0",
"Name": "Bruno's Fish Imports",
"Gln": "",
"Address": {
"City": "Curitiba",
"State": "Parana",
"Country": "Brazil",
"AddressLine1": "Av Presidente Wenceslau Braz, 1893",
"AddressLine2": "T2AP65",
"PostalCode": "81010001",
"GeoCoordinates": {
"Latitude": -25.441105,
"Longitude": -49.276855
}
}
},
"InputProducts": [
{
"Quantity": 1513.35,
"LotSerial": "899",
"Urn": "urn:gdst:wholechain.com:product:lot:class:brunosfishimports.salmonwhole.899",
"UOM": 1,
"ParentProduct": {
"Urn": "urn:gdst:wholechain.com:product:class:brunosfishimports.salmonwhole",
"Name": "Salmon Whole",
"SimpleUnitOfMeasurement": "Lbs",
"UnitQuantity": 0,
"SharingPolicy": "Open",
"ProductIdentifierType": "Lot",
"UnitDescriptor": None,
"Gtin": "",
"ProductMasterData": []
},
"TradePartnerName": "Bruno's Fish Imports",
"IdentifierType": "Lot"
}
],
"OutputProducts": [
{
"Quantity": 190.75,
"LotSerial": "1990091",
"Urn": "urn:gdst:wholechain.com:product:lot:class:brunosfishimports.salmoncut.1990091",
"UOM": "Lbs",
"Gtin": "",
"ParentProduct": {
"Urn": "urn:gdst:wholechain.com:product:class:brunosfishimports.salmoncut",
"Name": "Salmon Cut",
"SimpleUnitOfMeasurement": "Lbs",
"SharingPolicy": "Open",
"ProductIdentifierType": "Lot",
"ProductMasterData": [
{
"Name": "Species For Fishery Statistics Purposes Name",
"Namespace": "cbvmda",
"Value": "Salmo salar",
"ElementId": "speciesForFisheryStatisticsPurposesName"
},
{
"Name": "Trade Item Condition Code",
"Namespace": "cbvmda",
"Value": "RESPONSIBLY FARMED",
"ElementId": "tradeItemConditionCode"
}
]
},
"TradePartnerName": "Bruno's Fish Imports"
}
],
"ExternalEventId": "0002",
"Urn": "",
"PurchaseOrder": None,
"InvoiceNumber": "",
"BizStep": "urn:epcglobal:cbv:bizstep:commissioning",
"ReadPoint": None,
"Disposition": "urn:epcglobal:cbv:disp:active",
"EventTime": "2024-02-14T12:00:00+00:00",
"EventTimeZone": "-05:00",
"RecordTime": "2024-08-11T19:32:26.4146006+00:00",
"TradePartner": {
"Urn": "urn:gdst:wholechain.com:party:brunosfishimports.0",
"TradePartnerId": None,
"Name": "Bruno's Fish Imports",
"Pgln": "",
"ConnectionType": "SELF"
},
"CustomProperties": [],
"VesselCatchInformation": None,
"CertificationList": []
}
]
}
response = requests.post(url, headers=headers, json=data)
print(response.status_code)
print(response.json())
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace HttpClientExample
{
class Program
{
private static readonly HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
var url = "https://connect.wholechain.com/Integration/JSON";
var apiKey = "32459f03-6de9-44cc-a101-792934d35c6c";
var jsonData = @"{
""Events"": [
{
""$type"": ""transform"",
""Location"": {
""Urn"": ""urn:gdst:wholechain.com:location:loc:brunosfishimports.mainwarehouse"",
""TradePartnerUrn"": ""urn:gdst:wholechain.com:party:brunosfishimports.0"",
""Name"": ""Bruno's Fish Imports"",
""Gln"": """",
""Address"": {
""City"": ""Curitiba"",
""State"": ""Parana"",
""Country"": ""Brazil"",
""AddressLine1"": ""Av Presidente Wenceslau Braz, 1893"",
""AddressLine2"": ""T2AP65"",
""PostalCode"": ""81010001"",
""GeoCoordinates"": {
""Latitude"": -25.441105,
""Longitude"": -49.276855
}
}
},
""InputProducts"": [
{
""Quantity"": 1513.35,
""LotSerial"": ""899"",
""Urn"": ""urn:gdst:wholechain.com:product:lot:class:brunosfishimports.salmonwhole.899"",
""UOM"": 1,
""ParentProduct"": {
""Urn"": ""urn:gdst:wholechain.com:product:class:brunosfishimports.salmonwhole"",
""Name"": ""Salmon Whole"",
""SimpleUnitOfMeasurement"": ""Lbs"",
""UnitQuantity"": 0,
""SharingPolicy"": ""Open"",
""ProductIdentifierType"": ""Lot"",
""UnitDescriptor"": null,
""Gtin"": """",
""ProductMasterData"": []
},
""TradePartnerName"": ""Bruno's Fish Imports"",
""IdentifierType"": ""Lot""
}
],
""OutputProducts"": [
{
""Quantity"": 190.75,
""LotSerial"": ""1990091"",
""Urn"": ""urn:gdst:wholechain.com:product:lot:class:brunosfishimports.salmoncut.1990091"",
""UOM"": ""Lbs"",
""Gtin"": """",
""ParentProduct"": {
""Urn"": ""urn:gdst:wholechain.com:product:class:brunosfishimports.salmoncut"",
""Name"": ""Salmon Cut"",
""SimpleUnitOfMeasurement"": ""Lbs"",
""SharingPolicy"": ""Open"",
""ProductIdentifierType"": ""Lot"",
""ProductMasterData"": [
{
""Name"": ""Species For Fishery Statistics Purposes Name"",
""Namespace"": ""cbvmda"",
""Value"": ""Salmo salar"",
""ElementId"": ""speciesForFisheryStatisticsPurposesName""
},
{
""Name"": ""Trade Item Condition Code"",
""Namespace"": ""cbvmda"",
""Value"": ""RESPONSIBLY FARMED"",
""ElementId"": ""tradeItemConditionCode""
}
]
},
""TradePartnerName"": ""Bruno's Fish Imports""
}
],
""ExternalEventId"": ""0002"",
""Urn"": """",
""PurchaseOrder"": null,
""InvoiceNumber"": """",
""BizStep"": ""urn:epcglobal:cbv:bizstep:commissioning"",
""ReadPoint"": null,
""Disposition"": ""urn:epcglobal:cbv:disp:active"",
""EventTime"": ""2024-02-14T12:00:00+00:00"",
""EventTimeZone"": ""-05:00"",
""RecordTime"": ""2024-08-11T19:32:26.4146006+00:00"",
""TradePartner"": {
""Urn"": ""urn:gdst:wholechain.com:party:brunosfishimports.0"",
""TradePartnerId"": null,
""Name"": ""Bruno's Fish Imports"",
""Pgln"": """",
""ConnectionType"": ""SELF""
},
""CustomProperties"": [],
""VesselCatchInformation"": null,
""CertificationList"": []
}
]
}";
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
// Adding headers
client.DefaultRequestHeaders.Add("accept", "*/*");
client.DefaultRequestHeaders.Add("X-API-KEY", apiKey);
// Making the POST request
var response = await client.PostAsync(url, content);
// Checking and displaying the response
Console.WriteLine("Response Status Code: " + response.StatusCode);
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine("Response Content: " + responseContent);
}
}
}
curl -X POST 'https://connect.wholechain.com/Integration/JSON' \
-H 'accept: */*' \
-H 'X-API-KEY: 32459f03-6de9-44cc-a101-792934d35c6c' \
-H 'Content-Type: application/json' \
-d '{
"Events": [
{
"$type": "transform",
"Location": {
"Urn": "urn:gdst:wholechain.com:location:loc:brunosfishimports.mainwarehouse",
"TradePartnerUrn": "urn:gdst:wholechain.com:party:brunosfishimports.0",
"Name": "Bruno'\''s Fish Imports",
"Gln": "",
"Address": {
"City": "Curitiba",
"State": "Parana",
"Country": "Brazil",
"AddressLine1": "Av Presidente Wenceslau Braz, 1893",
"AddressLine2": "T2AP65",
"PostalCode": "81010001",
"GeoCoordinates": {
"Latitude": -25.441105,
"Longitude": -49.276855
}
}
},
"InputProducts": [
{
"Quantity": 1513.35,
"LotSerial": "899",
"Urn": "urn:gdst:wholechain.com:product:lot:class:brunosfishimports.salmonwhole.899",
"UOM": 1,
"ParentProduct": {
"Urn": "urn:gdst:wholechain.com:product:class:brunosfishimports.salmonwhole",
"Name": "Salmon Whole",
"SimpleUnitOfMeasurement": "Lbs",
"UnitQuantity": 0,
"SharingPolicy": "Open",
"ProductIdentifierType": "Lot",
"UnitDescriptor": null,
"Gtin": "",
"ProductMasterData": []
},
"TradePartnerName": "Bruno'\''s Fish Imports",
"IdentifierType": "Lot"
}
],
"OutputProducts": [
{
"Quantity": 190.75,
"LotSerial": "1990091",
"Urn": "urn:gdst:wholechain.com:product:lot:class:brunosfishimports.salmoncut.1990091",
"UOM": "Lbs",
"Gtin": "",
"ParentProduct": {
"Urn": "urn:gdst:wholechain.com:product:class:brunosfishimports.salmoncut",
"Name": "Salmon Cut",
"SimpleUnitOfMeasurement": "Lbs",
"SharingPolicy": "Open",
"ProductIdentifierType": "Lot",
"ProductMasterData": [
{
"Name": "Species For Fishery Statistics Purposes Name",
"Namespace": "cbvmda",
"Value": "Salmo salar",
"ElementId": "speciesForFisheryStatisticsPurposesName"
},
{
"Name": "Trade Item Condition Code",
"Namespace": "cbvmda",
"Value": "RESPONSIBLY FARMED",
"ElementId": "tradeItemConditionCode"
}
]
},
"TradePartnerName": "Bruno'\''s Fish Imports"
}
],
"ExternalEventId": "0002",
"Urn": "",
"PurchaseOrder": null,
"InvoiceNumber": "",
"BizStep": "urn:epcglobal:cbv:bizstep:commissioning",
"ReadPoint": null,
"Disposition": "urn:epcglobal:cbv:disp:active",
"EventTime": "2024-02-14T12:00:00+00:00",
"EventTimeZone": "-05:00",
"RecordTime": "2024-08-11T19:32:26.4146006+00:00",
"TradePartner": {
"Urn": "urn:gdst:wholechain.com:party:brunosfishimports.0",
"TradePartnerId": null,
"Name": "Bruno'\''s Fish Imports",
"Pgln": "",
"ConnectionType": "SELF"
},
"CustomProperties": [],
"VesselCatchInformation": null,
"CertificationList": []
}
]
}'
Example Responses
200
{'result': 'Success', 'message': None, 'errors': []}