{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "A Digital Traceability Event (DTE) credential. The credential subject is a list of GS1 EPCIS 2.0 events. Event semantics are defined by the GS1 EPCIS/CBV vocabulary; this schema defines only the W3C VCDM envelope and the linkage to the EPCIS event model.",
  "type": "object",
  "additionalProperties": true,
  "required": [
    "@context",
    "id",
    "issuer",
    "validFrom",
    "name",
    "credentialSubject"
  ],
  "properties": {
    "type": {
      "type": "array",
      "readOnly": true,
      "default": [
        "DigitalTraceabilityEvent",
        "VerifiableCredential"
      ],
      "items": {
        "type": "string"
      },
      "allOf": [
        {
          "contains": {
            "const": "DigitalTraceabilityEvent",
            "minContains": 1
          }
        },
        {
          "contains": {
            "const": "VerifiableCredential",
            "minContains": 1
          }
        }
      ]
    },
    "@context": {
      "type": "array",
      "readOnly": true,
      "description": "A list of JSON-LD context URIs that define the semantic meaning of properties within the credential. The W3C VCDM context, the UNTP context, and the GS1 EPCIS context MUST all be present, in that order. Further entries MAY be added, including inline context objects declaring extension namespaces used by the EPCIS events.",
      "example": [
        "https://www.w3.org/ns/credentials/v2",
        "https://vocabulary.uncefact.org/untp/0.8.0/context/",
        "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld",
        {
          "ext": "https://ns.example.com/epcis/"
        }
      ],
      "default": [
        "https://www.w3.org/ns/credentials/v2",
        "https://vocabulary.uncefact.org/untp/0.8.0/context/",
        "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"
      ],
      "prefixItems": [
        {
          "const": "https://www.w3.org/ns/credentials/v2",
          "type": "string"
        },
        {
          "const": "https://vocabulary.uncefact.org/untp/0.8.0/context/",
          "type": "string"
        },
        {
          "const": "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld",
          "type": "string"
        }
      ],
      "items": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "object"
          }
        ]
      },
      "minItems": 3,
      "uniqueItems": true
    },
    "id": {
      "example": "https://example-company.com/credentials/2a423366-a0d6-4855-ba65-2e0c926d09b0",
      "type": "string",
      "format": "uri",
      "description": "A unique identifier (URI) assigned to this verifiable credential."
    },
    "issuer": {
      "$ref": "#/$defs/IssuerParty",
      "description": "The organisation that is the issuer of this VC. The \"id\" property MUST be a W3C DID. Other identifiers, such as business or tax registration numbers, are listed in the \"issuerAlsoKnownAs\" property."
    },
    "validFrom": {
      "example": "2024-03-15T12:00:00Z",
      "type": "string",
      "format": "date-time",
      "description": "The date and time from which the credential is valid."
    },
    "validUntil": {
      "example": "2034-03-15T12:00:00Z",
      "type": "string",
      "format": "date-time",
      "description": "The expiry date (if applicable) of this verifiable credential."
    },
    "name": {
      "example": "Some name",
      "type": "string",
      "description": "Name of this verifiable credential instance."
    },
    "credentialStatus": {
      "oneOf": [
        {
          "$ref": "#/$defs/BitstringStatusListEntry"
        },
        {
          "type": "array",
          "items": {
            "$ref": "#/$defs/BitstringStatusListEntry"
          },
          "minItems": 1
        }
      ],
      "description": "A W3C VCDM2.0 compliant object, or array of such objects, containing credential status information."
    },
    "renderMethod": {
      "oneOf": [
        {
          "$ref": "#/$defs/RenderMethod"
        },
        {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/RenderMethod"
          }
        }
      ],
      "description": "Human rendering information for this credential. A single render method or an array of them. UNTP recommends SuiteRenderMethod but accepts any render method type, so each render method only needs a type, and a SuiteRenderMethod also needs a renderSuite."
    },
    "credentialSubject": {
      "type": "array",
      "minItems": 1,
      "description": "The GS1 EPCIS 2.0 event(s) that are the subject of this digital traceability event. Each item is an EPCIS event as defined by the GS1 EPCIS JSON Schema. Events do not carry their own @context: the GS1 EPCIS context is declared once at the credential level, exactly as it is for events inside an EPCISDocument.",
      "items": {
        "$ref": "#/$defs/EPCISEvent"
      }
    },
    "issuingSoftware": {
      "$ref": "#/$defs/IssuingSoftware",
      "description": "Optional metadata identifying the software product (and its vendor) that issued this credential."
    }
  },
  "$defs": {
    "EPCISEvent": {
      "description": "A GS1 EPCIS 2.0 event. The EPCIS context is declared at credential level, so events need not carry their own @context, exactly as events inside an EPCISDocument; a per-event @context is permitted but redundant. Resolves to the event union in the GS1 EPCIS JSON Schema, which dispatches on the 'type' property across ObjectEvent, AggregationEvent, TransactionEvent, TransformationEvent, AssociationEvent, and any extension event type identified by a URI. UNTP does not add, remove, or constrain any EPCIS event property.",
      "$ref": "https://ref.gs1.org/standards/epcis/2.0.0/epcis-json-schema.json#/definitions/EPCIS-Document-Event",
      "$comment": "The referenced GS1 schema declares draft-07. Validators built on draft 2020-12 must register the draft-07 meta-schema before compiling. Verified safe: the GS1 schema uses no draft-07-only constructs (no tuple-form items, no additionalItems, no dependencies, no $ref siblings), so it evaluates identically under both drafts."
    },
    "IssuerParty": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "type": "array",
          "readOnly": true,
          "default": [
            "Party"
          ],
          "items": {
            "type": "string"
          },
          "allOf": [
            {
              "contains": {
                "const": "Party",
                "minContains": 1
              }
            }
          ]
        },
        "id": {
          "example": "did:web:identifiers.example-company.com:12345",
          "type": "string",
          "format": "uri",
          "description": "The W3C DID of the issuer. did:web and did:webvh are the RECOMMENDED methods."
        },
        "name": {
          "example": "Example Company Pty Ltd",
          "type": "string",
          "description": "The name of the issuer person or organisation"
        },
        "alsoKnownAs": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "type": {
                "type": "array",
                "readOnly": true,
                "default": [
                  "Party"
                ],
                "items": {
                  "type": "string"
                },
                "allOf": [
                  {
                    "contains": {
                      "const": "Party",
                      "minContains": 1
                    }
                  }
                ]
              },
              "id": {
                "example": "https://sample-business-register.gov/123456789",
                "type": "string",
                "format": "uri",
                "description": "Globally unique identifier of this party. Typically represented as a URI identifierScheme/Identifier URI"
              },
              "name": {
                "example": "Sample Company Ltd",
                "type": "string",
                "description": "Legal registered name of this party."
              },
              "registeredId": {
                "example": 90664869327,
                "type": "string",
                "description": "The registration number (alphanumeric) of the Party within the register. Unique within the register."
              },
              "idScheme": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "array",
                    "readOnly": true,
                    "default": [
                      "IdentifierScheme"
                    ],
                    "items": {
                      "type": "string"
                    },
                    "allOf": [
                      {
                        "contains": {
                          "const": "IdentifierScheme",
                          "minContains": 1
                        }
                      }
                    ]
                  },
                  "id": {
                    "type": "string",
                    "format": "uri",
                    "description": "The URI of this identifier scheme"
                  },
                  "name": {
                    "example": "Global Identifier Scheme Name",
                    "type": "string",
                    "description": "The name of the identifier scheme. "
                  }
                },
                "required": [
                  "id",
                  "name"
                ],
                "description": "The identifier scheme of the registeredId - eg the register that issued this identifier."
              }
            },
            "required": [
              "id",
              "name"
            ]
          },
          "description": "An optional list of other registered identifiers for this credential issuer "
        }
      },
      "description": "The issuer party (person or organisation) of a verifiable credential.",
      "required": [
        "id",
        "name"
      ]
    },
    "BitstringStatusListEntry": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "BitstringStatusListEntry"
          ],
          "example": "BitstringStatusListEntry",
          "description": "The type of status list - must be set to \"The type property MUST be BitstringStatusListEntry.\""
        },
        "id": {
          "example": "https://example-cab.com/credentials/status/3#94567",
          "type": "string",
          "format": "uri",
          "description": "optional identifier of this status list entry."
        },
        "statusPurpose": {
          "type": "string",
          "examples": [
            "refresh",
            "revocation",
            "suspension",
            "message"
          ],
          "description": "Status purpose drawn from a standard list but extensible as per w3c bitstring status list specification."
        },
        "statusListIndex": {
          "example": "94567",
          "type": "string",
          "pattern": "^[0-9]+$",
          "description": "The statusListIndex property MUST be an arbitrary size integer greater than or equal to 0, expressed as a string in base 10. The value identifies the position of the status of the verifiable credential."
        },
        "statusListCredential": {
          "example": "https://example-cab.com/credentials/status/4",
          "type": "string",
          "format": "uri",
          "description": "The statusListCredential property MUST be a URL to a verifiable credential. When the URL is dereferenced, the resulting verifiable credential MUST have type property that includes the BitstringStatusListCredential value."
        },
        "statusSize": {
          "type": "integer",
          "minimum": 1
        },
        "statusMessage": {
          "type": "array",
          "minItems": 2,
          "items": {
            "type": "object",
            "required": [
              "status",
              "message"
            ],
            "properties": {
              "status": {
                "type": "string",
                "pattern": "^0x[0-9a-fA-F]+$"
              },
              "message": {
                "type": "string"
              }
            }
          }
        },
        "statusReference": {
          "oneOf": [
            {
              "type": "string",
              "format": "uri"
            },
            {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              }
            }
          ]
        }
      },
      "description": "A privacy-preserving, space-efficient, and high-performance mechanism for publishing status information such as suspension or revocation of Verifiable Credentials through use of bitstrings.  See https://www.w3.org/TR/vc-bitstring-status-list/ for full details.",
      "required": [
        "type",
        "statusPurpose",
        "statusListIndex",
        "statusListCredential"
      ],
      "allOf": [
        {
          "if": {
            "type": "object",
            "required": [
              "statusSize"
            ],
            "properties": {
              "statusSize": {
                "type": "integer",
                "minimum": 2
              }
            }
          },
          "then": {
            "type": "object",
            "required": [
              "statusMessage"
            ],
            "properties": {
              "statusMessage": {
                "type": "array"
              }
            }
          }
        },
        {
          "if": {
            "type": "object",
            "properties": {
              "statusSize": {
                "type": "integer",
                "const": 1
              }
            }
          },
          "then": {
            "type": "object",
            "properties": {
              "statusMessage": {
                "type": "array",
                "maxItems": 2
              }
            }
          }
        }
      ]
    },
    "RenderMethod": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "string"
              }
            }
          ],
          "description": "The type of render method, for example SuiteRenderMethod."
        }
      },
      "required": [
        "type"
      ],
      "if": {
        "properties": {
          "type": {
            "const": "SuiteRenderMethod"
          }
        },
        "required": [
          "type"
        ]
      },
      "then": {
        "$ref": "#/$defs/SuiteRenderMethod"
      },
      "description": "A render method as reserved by the W3C Verifiable Credentials Data Model v2.0. Any render method type is accepted. A render method whose type is SuiteRenderMethod is also checked against SuiteRenderMethod."
    },
    "SuiteRenderMethod": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "type": {
          "type": "string",
          "example": "SuiteRenderMethod",
          "description": "The type of render method. The W3C Working Draft of 6 October 2026 uses SuiteRenderMethod."
        },
        "id": {
          "example": "https://example-company.com/templates/dpp/1.0.0-render-method.json",
          "description": "Optional URL that dereferences to a hosted render method document."
        },
        "renderSuite": {
          "example": "html",
          "type": "string",
          "description": "Identifies the render suite, the set of algorithms used to produce the rendering. UNTP recommends html (an HTML fragment rendered in a sandbox). W3C also defines summary (a JSON template for wallet displays) and static (a pre-rendered payload such as an image, PDF or NFC message). Renderers ignore render methods whose suite they do not support."
        },
        "name": {
          "example": "Digital Product Passport - web view",
          "description": "Human-readable name that helps a person choose between render methods."
        },
        "description": {
          "description": "Human-readable description of when this render method is useful."
        },
        "renderProperty": {
          "example": [
            "/issuer/name",
            "/credentialSubject/name"
          ],
          "description": "JSON pointers (RFC 6901) to the credential properties exposed to the template. If omitted, the whole credential is exposed."
        },
        "template": {
          "description": "The template used to render the credential: a URL (a data: URL embeds the template inline), or an object with the template's id, mediaType and digestMultibase."
        },
        "deliveryMode": {
          "example": "nfc",
          "description": "The intended delivery method for a static render suite payload, for example nfc for transmission over NFC. Used by the static render suite only."
        },
        "digestMultibase": {
          "example": "uEiAsZMszMc45xiwf_IEpEQXL0gg4Fy3y_ngstaxUTC501Q",
          "description": "A multibase-encoded multihash (base64url with the 'u' prefix, SHA-256) of the render method document referenced by id. Renderers check the fetched content against this value, so a pinned render method cannot be changed without reissuing the credential. See https://www.w3.org/TR/2026/WD-vc-render-method-20261006/#suiterendermethod"
        },
        "outputPreference": {
          "description": "Optional hints about the preferred output, such as accessMode, mediaType and style."
        }
      },
      "description": "A render method as defined by the W3C Verifiable Credential Rendering Methods Working Draft of 6 October 2026. Only type and renderSuite are checked here; the W3C specification defines the remaining properties. See https://www.w3.org/TR/2026/WD-vc-render-method-20261006/#suiterendermethod",
      "required": [
        "type",
        "renderSuite"
      ]
    },
    "IssuingSoftware": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "example": "https://example.com/.well-known/untp/software/yourproduct/2026.04.1",
          "type": "string",
          "format": "uri",
          "description": "A resolvable identifier for the specific version of the software product that issued this credential."
        },
        "name": {
          "example": "Your Product Name",
          "type": "string",
          "description": "The name of the software product that issued this credential."
        },
        "version": {
          "example": "2026.04.1",
          "type": "string",
          "description": "The version of the software product that issued this credential."
        },
        "vendor": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "id": {
              "example": "did:web:example.com",
              "type": "string",
              "format": "uri",
              "description": "The decentralised identifier (DID) or other resolvable identifier of the software vendor."
            },
            "name": {
              "example": "Your Vendor Name",
              "type": "string",
              "description": "The name of the software vendor."
            }
          },
          "required": [
            "id",
            "name"
          ],
          "description": "The vendor of the software product that issued this credential."
        }
      },
      "required": [
        "id",
        "name",
        "version",
        "vendor"
      ],
      "description": "Optional metadata identifying the software product (and its vendor) that issued the parent credential. When present, all listed sub-properties MUST be populated; when absent, the credential is still valid (verifiers MUST treat the property as optional)."
    }
  }
}
