Add event
/supply-chain/data-space/inboxAuthorization
jwtBearerAuthScheme 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": "SupplyChainEvent", "typeCode": "twin:atLocationOfExit", "occurrenceDateTime": "2026-06-02T09:00:00.000Z", "occurrenceLocation": { "type": "Location", "name": "Port of Calais", "identifier": { "@type": "https://ref.gs1.org/voc/LocationID_Type-UN_LOCODE", "@value": "FRCQF" } } }, "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"}Records a status update against a consignment that already exists: goods despatched, arrived at a port, delivered. Events build the consignment's timeline, and some of them trigger notifications to other parties.
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 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 event
Use type: Add with a SupplyChainEvent in object to record a status update. You must also include a target that identifies which consignment the event belongs to — see Target.
Validation schema
| Field | Type | Required | Description |
|---|---|---|---|
@context | string | Yes | Must be "https://vocabulary.uncefact.org/unece-context-D23B.jsonld" |
typeCode | string | Yes | One of the twin:* event type codes — see Event types |
All other UNECE SupplyChainEvent fields are optional.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schema.twindev.org/supply-chain/SupplyChainAppEvent",
"title": "SupplyChainAppEvent",
"description": "Supply Chain App Event.",
"type": "object",
"properties": {
"@context": {
"$ref": "https://schema.twindev.org/unece/UneceContextType",
"description": "JSON-LD Context."
},
"typeCode": {
"anyOf": [
{
"$ref": "https://schema.twindev.org/unece/UneceSupplyChainEventTypeCodeList"
},
{
"type": "string"
}
],
"description": "A code specifying the type of supply chain event."
}
},
"required": [
"@context",
"typeCode"
],
"allOf": [
{
"$ref": "https://schema.twindev.org/unece/UneceSupplyChainEvent"
}
]
}Event types
typeCode | When to use |
|---|---|
twin:preNotification | Goods have been pre-notified ahead of departure |
twin:despatched | Goods have been despatched |
twin:issuedDocument | A document has been issued |
twin:onwardSharing | Data has been shared onward with another party |
twin:carrierBooking | A carrier booking has been confirmed |
twin:locationOperatorMatch | A location operator has matched the consignment |
twin:atLocationOfExit | Goods have arrived at the exit location |
twin:leftLocationOfExit | Goods have left the exit location |
twin:atLocationOfEntry | Goods have arrived at the entry location |
twin:leftLocationOfEntry | Goods have left the entry location |
twin:arrivedAtFinalDestination | Goods have been delivered |
twin:locationOperatorMatch is the one event that is not sent by freight forwarders: location
operators send it to confirm a consignment routed through their facility. See the Location
Operator tutorial.
Target
Identifies the consignment to attach the event to. Required for all Add activities.
| Field | Type | Required | Value |
|---|---|---|---|
@context | string | Yes | "https://vocabulary.uncefact.org/unece-context-D23B.jsonld" |
type | string | Yes | "Consignment" |
globalId | string | Yes | The consignment's globalId |
identifier | string | Yes | The consignment's identifier |
Notifying goods arrived at the exit location (Example)
An event with timestamp and location, attached to an existing consignment. The event's occurrenceLocation is a Location — unlike the LogisticsLocation used inside transport movements — and carries its UN/LOCODE in identifier.
{
"@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": "SupplyChainEvent",
"typeCode": "twin:atLocationOfExit",
"occurrenceDateTime": "2026-06-02T09:00:00.000Z",
"occurrenceLocation": {
"type": "Location",
"name": "Port of Calais",
"identifier": {
"@type": "https://ref.gs1.org/voc/LocationID_Type-UN_LOCODE",
"@value": "FRCQF"
}
}
},
"target": {
"@context": "https://vocabulary.uncefact.org/unece-context-D23B.jsonld",
"type": "Consignment",
"identifier": "ACME-2026-001",
"globalId": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}Actor
Your organisation as a UNECE TradeParty. Use the same value on every request.
| Field | Type | Required | Description |
|---|---|---|---|
@context | string | Yes | Always "https://vocabulary.uncefact.org/unece-context-D23B.jsonld" |
type | string | Yes | Always "TradeParty" |
registeredId | object | Yes | Your 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.
| Status | Cause |
|---|---|
400 | Malformed activity — not an object, or no type |
401 | Missing or invalid credentials |
500 | The activity could not be submitted to the data space |