TWIN Supply Chain Docs
API ReferencePublish Data

Add document

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": "Add",    "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": "Document",      "documentTypeCode": "unece:DocumentCodeList#271",      "identifier": "CUSTOMS-DOC-001",      "versionId": "v1",      "issueDateTime": "2026-06-01T14:00:00.000Z",      "uRIId": "https://docs.your-org.example.com/CUSTOMS-DOC-001.pdf"    },    "target": {      "@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"}

Attaches a document — a customs declaration, certificate, or bill of lading — to a consignment that already exists.

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

TWIN stores the file itself, not just a reference to it. Send the content as base64 in attachmentBinaryObject, or host it and let TWIN fetch it once from uRIId — either way the node keeps the bytes in encrypted storage and serves them from its own origin, so the URL does not have to stay reachable afterwards.


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 identifies the consignment this attaches to. actor is your organisation and is the same on every request — see Actor.

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

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 document

Use type: Add with a Document in object to attach a file to a consignment. You must also include a target that identifies which consignment the document belongs to — see Target.

Validation schema

FieldTypeRequiredDescription
@contextstringYesMust be "https://vocabulary.uncefact.org/unece-context-D23B.jsonld"
typestringYesAlways "Document"
documentTypeCodestringYesUNECE document type code
identifierstringYesYour reference for this document
issueDateTimestringYesISO 8601 datetime
uRIIdstringYesURL for the file — TWIN fetches from it when attachmentBinaryObject is absent
versionIdstringYesVersion identifier
attachmentBinaryObjectstringNoThe file itself, base64 encoded
{
	"$schema": "https://json-schema.org/draft/2020-12/schema",
	"$id": "https://schema.twindev.org/supply-chain/SupplyChainAppDocument",
	"title": "SupplyChainAppDocument",
	"description": "Supply Chain App Document.",
	"type": "object",
	"properties": {
		"@context": {
			"$ref": "https://schema.twindev.org/unece/UneceContextType",
			"description": "JSON-LD Context."
		},
		"type": {
			"const": "Document",
			"description": "JSON-LD Type."
		},
		"documentTypeCode": {
			"$ref": "https://schema.twindev.org/unece/UneceDocumentCodeList",
			"description": "The code specifying the type of referenced document."
		},
		"identifier": {
			"anyOf": [
				{
					"type": "string"
				},
				{
					"$ref": "https://schema.twindev.org/json-ld/JsonLdValueObject"
				}
			],
			"description": "A unique identifier for this referenced document."
		},
		"issueDateTime": {
			"type": "string",
			"description": "The formatted date or date time for the issuance of this referenced document.",
			"format": "date-time"
		},
		"uRIId": {
			"anyOf": [
				{
					"type": "string"
				},
				{
					"$ref": "https://schema.twindev.org/json-ld/JsonLdValueObject"
				}
			],
			"description": "The unique Uniform Resource Identifier (URI) for this referenced document."
		},
		"versionId": {
			"anyOf": [
				{
					"type": "string"
				},
				{
					"$ref": "https://schema.twindev.org/json-ld/JsonLdValueObject"
				}
			],
			"description": "The identifier for the version of this referenced document."
		}
	},
	"required": [
		"@context",
		"type",
		"documentTypeCode",
		"identifier",
		"issueDateTime",
		"uRIId",
		"versionId"
	],
	"allOf": [
		{
			"$ref": "https://schema.twindev.org/unece/UneceDocument"
		}
	]
}

uRIId is always required by the schema, but it is not always where the content comes from: the request must carry the file in either attachmentBinaryObject or a uRIId TWIN can fetch. Sending neither is rejected. When both are present, attachmentBinaryObject is used and no fetch is made.

Attaching a document to a consignment (Example)

A document with type code, version, issue date, and a uRIId for TWIN to fetch the file from. To send the bytes directly instead, add attachmentBinaryObject.

{
  "@context": ["https://www.w3.org/ns/activitystreams"],
  "type": "Add",
  "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": "Document",
    "documentTypeCode": "unece:DocumentCodeList#271",
    "identifier": "CUSTOMS-DOC-001",
    "versionId": "v1",
    "issueDateTime": "2026-06-01T14:00:00.000Z",
    "uRIId": "https://docs.acme-freight.example.com/CUSTOMS-DOC-001.pdf"
  },
  "target": {
    "@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",
    "type": "Consignment",
    "identifier": "ACME-2026-001",
    "globalId": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Target

Identifies the consignment to attach to. Required for all Add activities.

FieldTypeRequiredValue
@contextstringYes"https://vocabulary.uncefact.org/unece-context-D23B.jsonld"
typestringYes"Consignment"
globalIdstringYesThe consignment's globalId
identifierstringYesThe consignment's identifier

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