TWIN Supply Chain Docs
API ReferencePublish Data

Create consignment

POST/supply-chain/data-space/inbox

Authorization

jwtBearerAuthScheme
AuthorizationBearer <token>

In: header

Request Body

application/json

Request to notify the dataspace inbox via the simplified session-auth facade. The caller supplies only the activity; the server injects the generator and the trust credential and ensures the underlying dataspace transfer.

TypeScript Definitions

Use the request body type in TypeScript.

A JSON-LD node object: free-form properties describing a node in the graph.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/supply-chain/data-space/inbox" \  -H "Content-Type: application/json" \  -d '{    "@context": [      "https://www.w3.org/ns/activitystreams"    ],    "type": "Create",    "actor": {      "@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",      "type": "TradeParty",      "registeredId": {        "@type": "https://ref.gs1.org/voc/OrganizationID_Type-DID",        "@value": "did:web:your-org.example.com"      }    },    "object": {      "@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",      "type": "Consignment",      "identifier": "MYREF-001",      "globalId": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890"    }  }'
{}
{  "name": "GeneralError",  "message": "errorMessage",  "properties": {    "foo": "bar"  }}
{  "name": "UnauthorizedError",  "message": "errorMessage"}
{  "name": "InternalServerError",  "message": "errorMessage"}

Publishes a new consignment to the dataspace. TWIN routes it to the relevant border agencies and location operators automatically, based on its ports of exit and entry.

Every request requires Cookie: access_token=<jwt>. See Authentication.


Every request body is an activity: a JSON wrapper with a type that tells TWIN what to do, and an object that carries the payload. target is not used by this activity. actor is your organisation and is the same on every request — see Actor.

{
  "@context": ["https://www.w3.org/ns/activitystreams"],
  "type": "Create",
  "actor": { ... },
  "object": { ... }
}

Activity schema

The full activity schema including required fields, actor, object, and target:

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://schema.twindev.org/supply-chain/SupplyChainAppActivity",
	"title": "SupplyChainAppActivity",
	"description": "Supply Chain App Activity.",
	"type": "object",
	"properties": {
		"actor": {
			"$ref": "https://schema.twindev.org/supply-chain/SupplyChainAppActor",
			"description": "The actor responsible for the activity."
		},
		"object": {
			"$ref": "https://schema.twindev.org/supply-chain/SupplyChainAppObject",
			"description": "Activity's object."
		},
		"target": {
			"type": "object",
			"properties": {
				"@context": {
					"const": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld"
				},
				"type": {
					"const": "Consignment"
				},
				"identifier": {
					"type": "string"
				},
				"globalId": {
					"type": "string"
				}
			},
			"required": [
				"@context",
				"type",
				"identifier",
				"globalId"
			],
			"description": "Target information."
		}
	},
	"required": [
		"actor",
		"object"
	],
	"allOf": [
		{
			"description": "A dataspace activity that restricts an activity so that it can be handled by a Dataspace Data Plane",
			"type": "object",
			"properties": {
				"@context": {
					"$ref": "https://schema.twindev.org/w3c-activity-streams/ActivityStreamsContextType",
					"description": "The LD Context.",
					"$comment": "Inherited from ActivityStreamsActivity"
				},
				"type": {
					"anyOf": [
						{
							"$ref": "https://schema.twindev.org/w3c-activity-streams/ActivityStreamsTypes"
						},
						{
							"type": "string"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"$ref": "https://schema.twindev.org/w3c-activity-streams/ActivityStreamsTypes"
									},
									{
										"type": "string"
									}
								]
							}
						}
					],
					"description": "Activity Type.",
					"$comment": "Inherited from ActivityStreamsActivity"
				},
				"id": {
					"type": "string",
					"description": "Global identifier.",
					"format": "uri",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"name": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdLanguageMap"
						}
					],
					"description": "Natural language name.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"nameMap": {
					"$ref": "https://schema.twindev.org/json-ld/JsonLdLanguageMap",
					"description": "Natural language name map.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"summary": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdLanguageMap"
						}
					],
					"description": "Summary of the Activity.",
					"$comment": "Inherited from ActivityStreamsActivity"
				},
				"summaryMap": {
					"$ref": "https://schema.twindev.org/json-ld/JsonLdLanguageMap",
					"description": "Natural language summary map.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"content": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdLanguageMap"
						}
					],
					"description": "Natural language content.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"contentMap": {
					"$ref": "https://schema.twindev.org/json-ld/JsonLdLanguageMap",
					"description": "Natural language content map.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"url": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "A link to the representation of the object.\n\nThe value can be a URI or an embedded node object.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"image": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "A graphical representation of the object.\n\nThe value can be a URI or an embedded `Image`/`Link` object.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"icon": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "An icon for the object.\n\nThe value can be a URI or an embedded `Image`/`Link` object.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"published": {
					"type": "string",
					"description": "Published date-time.",
					"format": "date-time",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"updated": {
					"type": "string",
					"description": "Updated date-time.",
					"format": "date-time",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"startTime": {
					"type": "string",
					"description": "Start time.",
					"format": "date-time",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"endTime": {
					"type": "string",
					"description": "End time.",
					"format": "date-time",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"duration": {
					"type": "string",
					"description": "Duration.",
					"format": "duration",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"generator": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "The generator of the Activity.",
					"$comment": "Inherited from ActivityStreamsActivity"
				},
				"attachment": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Attachments.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"attributedTo": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Objects attributed to.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"audience": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Audience.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"context": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Context.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"location": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Location.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"tag": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Tag.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"inReplyTo": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "In reply to.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"replies": {
					"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject",
					"description": "Replies collection.\n\nTypically an embedded `Collection` of Objects that are replies to this object.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"preview": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Preview.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"to": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "To.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"bto": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "BTo.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"cc": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "CC.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"bcc": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "BCC.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"mediaType": {
					"type": "string",
					"description": "MIME media type of the referenced resource.",
					"$comment": "Inherited from ActivityStreamsObject"
				},
				"result": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Result of the Activity.",
					"$comment": "Inherited from ActivityStreamsActivity"
				},
				"origin": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Activity's origin.",
					"$comment": "Inherited from ActivityStreamsActivity"
				},
				"instrument": {
					"anyOf": [
						{
							"type": "string"
						},
						{
							"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
						},
						{
							"type": "array",
							"items": {
								"anyOf": [
									{
										"type": "string"
									},
									{
										"$ref": "https://schema.twindev.org/json-ld/JsonLdNodeObject"
									}
								]
							}
						}
					],
					"description": "Instrument used in the Activity.",
					"$comment": "Inherited from ActivityStreamsActivity"
				}
			},
			"required": [
				"@context",
				"type"
			],
			"$comment": "Inlined utility base type DataspaceActivity so utility transformations can operate on concrete properties instead of a $ref."
		}
	]
}

The consignment

Three fields are always required in object: @context, identifier, and globalId. All UNECE D23B fields are optional and validated when present.

FieldTypeRequiredDescription
@contextstringYesMust be "https://vocabulary.uncefact.org/unece-context-D23B.jsonld"
identifierstringYesYour internal reference for this consignment
globalIdstringYesA globally unique ID — use a UUID URN: urn:uuid:<uuid>

Validation schema

Defines what TWIN accepts and validates. Required fields are @context, identifier, and globalId — all other UNECE D23B fields are optional.

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://schema.twindev.org/supply-chain/SupplyChainAppConsignment",
	"title": "SupplyChainAppConsignment",
	"description": "V2 consignment (D23B context).\nAll extended fields are optional for ingestion but validated if present.\nOnly minimal identity fields are required; all other UNECE fields are optional but validated if present.",
	"type": "object",
	"properties": {
		"@context": {
			"$ref": "https://schema.twindev.org/unece/UneceContextType",
			"description": "JSON-LD Context."
		},
		"globalId": {
			"anyOf": [
				{
					"type": "string"
				},
				{
					"$ref": "https://schema.twindev.org/json-ld/JsonLdValueObject"
				}
			],
			"description": "A global identifier of this supply chain consignment."
		},
		"identifier": {
			"anyOf": [
				{
					"type": "string"
				},
				{
					"$ref": "https://schema.twindev.org/json-ld/JsonLdValueObject"
				}
			],
			"description": "A unique identifier for this referenced supply chain consignment."
		},
		"consignmentItemQuantity": {
			"$ref": "https://schema.twindev.org/supply-chain/WrappedQuantity",
			"description": "Wrapped quantity structures."
		},
		"packageQuantity": {
			"$ref": "https://schema.twindev.org/supply-chain/WrappedQuantity",
			"description": "Wrapped package quantity."
		},
		"weightUnitNetWeightMeasure": {
			"type": "array",
			"items": {
				"$ref": "https://schema.twindev.org/supply-chain/WrappedWeightMeasure"
			},
			"description": "Wrapped weight net measurement"
		}
	},
	"required": [
		"@context",
		"globalId",
		"identifier"
	],
	"allOf": [
		{
			"$ref": "https://schema.twindev.org/unece/UneceConsignment"
		}
	]
}

For quantity and weight fields, TWIN uses wrapper objects that pair a numeric value with a unit code:

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://schema.twindev.org/supply-chain/WrappedQuantity",
	"title": "WrappedQuantity",
	"description": "Wrapped UNECE quantity structure (D23B).",
	"type": "object",
	"properties": {
		"unece:QuantityTypeValue": {
			"type": "string",
			"description": "Quantity numeric value."
		},
		"unece:QuantityTypeCode": {
			"$ref": "https://schema.twindev.org/unece/UneceQuantityCode",
			"description": "Unit of measure code."
		}
	},
	"required": [
		"unece:QuantityTypeValue"
	],
	"allOf": [
		{
			"$ref": "https://schema.twindev.org/unece/UneceQuantityType"
		}
	]
}
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://schema.twindev.org/supply-chain/WrappedWeightMeasure",
	"title": "WrappedWeightMeasure",
	"description": "Wrapped UNECE weight measure structure.",
	"type": "object",
	"properties": {
		"unece:WeightUnitMeasureTypeValue": {
			"type": "string",
			"description": "Weight measure numeric value."
		},
		"unece:WeightUnitMeasureTypeCode": {
			"$ref": "https://schema.twindev.org/unece/UneceWeightUnitMeasureCode",
			"description": "Unit of measure code."
		}
	},
	"required": [
		"unece:WeightUnitMeasureTypeValue"
	],
	"allOf": [
		{
			"$ref": "https://schema.twindev.org/unece/UneceWeightUnitMeasureType"
		}
	]
}

Routing is derived from the consignment's ports of exit and entry. A consignment without transport movements is stored and readable, but TWIN has nothing to route it on, so no border agency or location operator is notified.

Keep the identifier and globalId you publish here. Every later operation on this consignment — updates, events, documents — identifies it by those two values, and reading it back needs one of them.


Publishing a new consignment (Example)

Required fields plus the journey — departure and arrival movements, the goods, and the parties trading them.

{
  "@context": ["https://www.w3.org/ns/activitystreams"],
  "type": "Create",
  "actor": {
    "@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",
    "type": "TradeParty",
    "registeredId": {
      "@type": "https://ref.gs1.org/voc/OrganizationID_Type-DID",
      "@value": "did:web:acme-freight.example.com"
    }
  },
  "object": {
    "@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",
    "type": "Consignment",
    "identifier": "ACME-2026-001",
    "globalId": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "summaryDescription": "RORO vehicle consignment",
    "packageQuantity": {
      "type": "QuantityType",
      "unece:QuantityTypeValue": "12"
    },
    "atDepartureTransportMovement": {
      "type": "TransportMovement",
      "transportModeCode": "unece:TransportModeCodeList#1",
      "departureEvent": [
        {
          "type": "TransportEvent",
          "scheduledOccurrenceDateTime": "2026-06-01T08:00:00.000Z",
          "occurrenceLogisticsLocation": {
            "type": "LogisticsLocation",
            "name": "Port of Calais",
            "identifier": {
              "@type": "https://ref.gs1.org/voc/LocationID_Type-UN_LOCODE",
              "@value": "FRCQF"
            }
          }
        }
      ],
      "usedTransportMeans": {
        "type": "LogisticsTransportMeans",
        "transportMeansTypeCode": "unece:TransportMeansTypeCodeList#1512",
        "identifier": { "@value": "Channel Voyager" }
      }
    },
    "atArrivalTransportMovement": {
      "type": "TransportMovement",
      "transportModeCode": "unece:TransportModeCodeList#1",
      "arrivalEvent": [
        {
          "type": "TransportEvent",
          "scheduledOccurrenceDateTime": "2026-06-01T14:30:00.000Z",
          "occurrenceLogisticsLocation": {
            "type": "LogisticsLocation",
            "name": "Port of Felixstowe",
            "identifier": {
              "@type": "https://ref.gs1.org/voc/LocationID_Type-UN_LOCODE",
              "@value": "GBFXT"
            }
          }
        }
      ]
    },
    "utilizedTransportEquipment": [
      {
        "type": "LogisticsTransportEquipment",
        "identifier": "TRAILER-XY-1"
      }
    ],
    "includedConsignment": [
      {
        "type": "Consignment",
        "identifier": "ITEM-001",
        "consignorParty": {
          "type": "TradeParty",
          "name": "Acme Exports Ltd",
          "postalAddress": {
            "type": "TradeAddress",
            "tradeAddressCountryId": "unece:CountryId#FR"
          }
        },
        "consigneeParty": {
          "type": "TradeParty",
          "name": "UK Imports Co",
          "postalAddress": {
            "type": "TradeAddress",
            "tradeAddressCountryId": "unece:CountryId#GB"
          }
        },
        "includedConsignmentItem": [
          {
            "type": "ConsignmentItem",
            "goodsTypeCode": "unece:GoodsTypeCodeList#ZZZ",
            "information": "12 pallets of automotive parts",
            "originCountry": {
              "type": "Country",
              "countryId": "unece:CountryId#FR"
            }
          }
        ]
      }
    ]
  }
}

Everything you send is stored and returned by Get a Consignment, but the summary shown in the consignment list is built from specific fields:

You sendWhere it appears in the list
atDeparture/atArrivalTransportMovementoccurrenceLogisticsLocationPort of exit and port of entry — see below
arrivalEventscheduledOccurrenceDateTimeEstimated date of entry
departureEventscheduledOccurrenceDateTimeThe date carried on the consignment's status
atDepartureTransportMovement.transportModeCodeTransport mode
utilizedTransportEquipmentTransport means and the transport reference
includedConsignmentconsignorParty/consigneePartyFirst consignor and last consignee
includedConsignmentincludedConsignmentItemCommodities

Locations carry their UN/LOCODE in identifier — a five-character code with the LocationID_Type-UN_LOCODE type — and their human-readable name in name. For the list summary, the consignor and consignee are taken from includedConsignment and the transport mode only from atDepartureTransportMovement; parties sent at the top level are kept and returned with the consignment, but do not populate those columns.

How ports of entry and exit are derived

The ports are not sent as fields of their own. TWIN derives them from the arrival and departure movements, and from nowhere else:

PortDerived from
Port of exitatDepartureTransportMovement.departureEvent[0].occurrenceLogisticsLocation
Port of entryatArrivalTransportMovement.arrivalEvent[0].occurrenceLogisticsLocation

Each location's name gives the port its display value, and its identifier gives the UN/LOCODE — two ISO country letters followed by three alphanumeric characters, from which the country is taken:

"occurrenceLogisticsLocation": {
  "type": "LogisticsLocation",
  "name": "Hoek van Holland",
  "identifier": {
    "@type": "https://ref.gs1.org/voc/LocationID_Type-UN_LOCODE",
    "@value": "NLHVH"
  }
}

Two rules follow:

  • Only the first event counts. departureEvent and arrivalEvent are arrays; entries after [0] are stored and returned, but do not affect the ports.
  • No other location property feeds them. The consignment's own loading and unloading locations are valid UN/CEFACT properties and are stored with the consignment, but do not set the ports.

The country behind the port of entry is what data-sharing rules match on. Without a well-formed UN/LOCODE there is no country, so a border agency's access rule cannot match the consignment: it is not shared with them and no notification is sent. The publish still returns 200 OK.

Publishing a consignment with multiple items (Example)

A consignment can carry several goods items in includedConsignment — each one is itself a Consignment with its own identifier, and describes its goods via includedConsignmentItem.

{
  "@context": ["https://www.w3.org/ns/activitystreams"],
  "type": "Create",
  "actor": {
    "@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",
    "type": "TradeParty",
    "registeredId": {
      "@type": "https://ref.gs1.org/voc/OrganizationID_Type-DID",
      "@value": "did:web:acme-freight.example.com"
    }
  },
  "object": {
    "@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",
    "type": "Consignment",
    "identifier": "ACME-2026-002",
    "globalId": "urn:uuid:b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "summaryDescription": "Mixed consignment: fresh chicken and electronics",
    "includedConsignment": [
      {
        "type": "Consignment",
        "identifier": "ITEM-001",
        "consignorParty": {
          "type": "TradeParty",
          "name": "Traders International",
          "postalAddress": {
            "type": "TradeAddress",
            "tradeAddressCountryId": "unece:CountryId#PL"
          }
        },
        "includedConsignmentItem": [
          {
            "type": "ConsignmentItem",
            "goodsTypeCode": "unece:GoodsTypeCodeList#ZZZ",
            "information": "500 live chickens",
            "originCountry": {
              "type": "Country",
              "countryId": "unece:CountryId#PL"
            }
          }
        ]
      },
      {
        "type": "Consignment",
        "identifier": "ITEM-002",
        "consignorParty": {
          "type": "TradeParty",
          "name": "EuroTech GmbH",
          "postalAddress": {
            "type": "TradeAddress",
            "tradeAddressCountryId": "unece:CountryId#DE"
          }
        },
        "includedConsignmentItem": [
          {
            "type": "ConsignmentItem",
            "goodsTypeCode": "unece:GoodsTypeCodeList#ZZZ",
            "information": "40 pallets of consumer electronics",
            "originCountry": {
              "type": "Country",
              "countryId": "unece:CountryId#DE"
            }
          }
        ]
      }
    ]
  }
}

Actor

Your organisation as a UNECE TradeParty. Use the same value on every request.

FieldTypeRequiredDescription
@contextstringYesAlways "https://vocabulary.uncefact.org/unece-context-D23B.jsonld"
typestringYesAlways "TradeParty"
registeredIdobjectYesYour organisation's DID — { "@type": "...", "@value": "did:web:your-org.example.com" }

Validation schema

{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://schema.twindev.org/supply-chain/SupplyChainAppActor",
	"title": "SupplyChainAppActor",
	"description": "Supply Chain App Actor.",
	"type": "object",
	"properties": {
		"type": {
			"const": "TradeParty",
			"description": "Actor information."
		},
		"registeredId": {
			"type": "object",
			"properties": {
				"@type": {
					"type": "string"
				},
				"@value": {
					"type": "string"
				}
			},
			"required": [
				"@type",
				"@value"
			],
			"description": "Registered identifier for the actor."
		},
		"@context": {
			"const": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",
			"description": "Context for the actor."
		}
	},
	"required": [
		"type",
		"registeredId",
		"@context"
	],
	"allOf": [
		{
			"$ref": "https://schema.twindev.org/unece/UneceTradeParty"
		}
	]
}

Response

200 OK — the activity was accepted. The response is an activity-log entry describing how it was processed.

{
  "id": "urn:x-activity-log:0199f3b1...",
  "status": "completed",
  "generator": "urn:uuid:...",
  "dateCreated": "2026-06-30T14:00:00.000Z",
  "dateModified": "2026-06-30T14:00:00.001Z",
  "tasks": [
    {
      "taskId": "...",
      "dataspaceAppId": "SupplyChainDataSpaceConnectorApp",
      "result": 0,
      "startDate": "2026-06-30T14:00:00.000Z",
      "endDate": "2026-06-30T14:00:00.001Z",
      "status": "success"
    }
  ]
}

id identifies the activity-log entry, not the consignment. This response carries no consignment id — read the consignment back with the globalId or identifier you published, which Get a Consignment accepts directly.

Accepting the activity is not the same as processing it successfully. A failure inside the supply chain app still comes back as 200, with the reason on the task rather than in the HTTP status — always check the entry's status (completed or error) and each task's status (success or failed):

{
  "id": "urn:x-activity-log:0199f3b1...",
  "status": "error",
  "tasks": [
    {
      "taskId": "...",
      "dataspaceAppId": "SupplyChainDataSpaceConnectorApp",
      "status": "failed",
      "error": {
        "name": "UnprocessableError",
        "source": "DataspaceDataPlaneService",
        "message": "dataspaceDataPlaneService.activitySemanticError",
        "cause": {
          "name": "ValidationError",
          "message": "..."
        }
      }
    }
  ]
}

That is the shape a schema validation failure takes: an UnprocessableError wrapping the ValidationError that describes the offending field.

Errors

Only failures raised before the activity is handed to the supply chain app surface as HTTP errors. Anything the app itself rejects — including schema validation — comes back as 200 with the error on the task.

StatusCause
400Malformed activity — not an object, or no type
401Missing or invalid credentials
500The activity could not be submitted to the data space