{
  "openapi": "3.1.0",
  "info": {
    "title": "GDST API",
    "version": "2.0.0",
    "description": "The GDST 2.0 profile of the GS1 EPCIS 2.0 REST binding.\n\nGDST requires a defined subset of that binding, and this document describes only that subset: `GET /events`, a GS1 Digital Link resolver, and the `X-API-Key` header. Everything here is mandatory for a conforming solution.\n\nExchange is pull-based. The receiving party resolves the sending party's identifier to find their EPCIS repository, then queries it. Responses are EPCIS 2.0 JSON-LD. Master data is never embedded in events; it is resolved through the `gs1:masterData` link.\n\nThe seven core events are plain EPCIS, with CBV business steps. Their signatures are in `x-gdst-core-events`. Commodity-specific KDEs are added by the Seafood, Aquaculture and Wild Catch modules, which constrain payloads but add no HTTP surface, and so are out of scope here.",
    "contact": {
      "name": "Global Dialogue on Seafood Traceability",
      "url": "https://thegdst.org/"
    },
    "license": {
      "name": "Apache-2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0"
    }
  },
  "externalDocs": {
    "description": "GDST developer documentation",
    "url": "https://developer.thegdst.org/"
  },
  "x-gdst-core-events": {
    "description": "The immutable EPCIS signature of each GDST 2.0 core event. Values are shown JSON-LD compacted, as they appear in a payload.\n\n`commonRequiredFields` applies to all seven and is not repeated per event. Beyond it, a field appears under an event only where the standard fixes its value. `optional` lists fields the event may carry but whose value the standard does not fix; those values must come from the CBV vocabulary at https://ref.gs1.org/cbv. A field in neither list is absent from the event type altogether — TransformationEvent has no `action` in EPCIS.\n\nCommission and Transformation share `commissioning`; `type` tells them apart.",
    "commonRequiredFields": {
      "fields": [
        "eventID",
        "eventTime",
        "eventTimeZoneOffset",
        "bizLocation"
      ],
      "eventID": "Identifier of the event, so it can be referenced later.",
      "eventTime": "When the event happened.",
      "eventTimeZoneOffset": "UTC offset for eventTime, e.g. +00:00.",
      "bizLocation": "The facility or node the event took place at."
    },
    "productIdentification": "Every core event identifies its products by serialized instances, by lot/class quantities, or by both in the same event. Quantity entries carry `epcClass`, `quantity` and `uom`. The per-event `productIdentification` list names the fields that event uses; at least one must be present.",
    "events": [
      {
        "name": "Commission",
        "eventType": "ObjectEvent",
        "action": "ADD",
        "bizStep": "commissioning",
        "disposition": "active",
        "productIdentification": [
          "epcList",
          "quantityList"
        ]
      },
      {
        "name": "Decommission",
        "eventType": "ObjectEvent",
        "action": "DELETE",
        "bizStep": "destroying",
        "productIdentification": [
          "epcList",
          "quantityList"
        ],
        "optional": [
          "disposition"
        ],
        "dispositionGuidance": "`inactive` for an object that may be reintroduced into the supply chain, `destroyed` for one rendered non-usable."
      },
      {
        "name": "Aggregation",
        "eventType": "AggregationEvent",
        "action": "ADD",
        "bizStep": "packing",
        "disposition": "active",
        "productIdentification": [
          "childEPCs",
          "childQuantityList"
        ],
        "alsoRequired": [
          "parentID"
        ]
      },
      {
        "name": "Disaggregation",
        "eventType": "AggregationEvent",
        "action": "DELETE",
        "bizStep": "unpacking",
        "disposition": "inactive",
        "productIdentification": [
          "childEPCs",
          "childQuantityList"
        ],
        "alsoRequired": [
          "parentID"
        ]
      },
      {
        "name": "Shipping",
        "eventType": "ObjectEvent",
        "action": "OBSERVE",
        "bizStep": "shipping",
        "disposition": "in_transit",
        "productIdentification": [
          "epcList",
          "quantityList"
        ],
        "alsoRequired": [
          "sourceList",
          "destinationList"
        ]
      },
      {
        "name": "Receiving",
        "eventType": "ObjectEvent",
        "action": "OBSERVE",
        "bizStep": "receiving",
        "productIdentification": [
          "epcList",
          "quantityList"
        ],
        "alsoRequired": [
          "sourceList",
          "destinationList"
        ],
        "optional": [
          "disposition"
        ],
        "dispositionGuidance": "`in_progress`, `active` or `sellable_accessible` in the normal case; `damaged`, `expired` or `recalled` to flag a problem found at receipt."
      },
      {
        "name": "Transformation",
        "eventType": "TransformationEvent",
        "bizStep": "commissioning",
        "disposition": "active",
        "productIdentification": [
          "inputEPCList",
          "inputQuantityList",
          "outputEPCList",
          "outputQuantityList"
        ],
        "alsoRequired": [
          "transformationID"
        ]
      }
    ]
  },
  "servers": [
    {
      "url": "https://{host}/{basePath}",
      "description": "A GDST-compliant EPCIS repository and Digital Link resolver.",
      "variables": {
        "host": {
          "default": "example.org"
        },
        "basePath": {
          "default": "",
          "description": "Optional path prefix."
        }
      }
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "digitallink",
      "description": "GS1 Digital Link resolver. Turns an identifier into links to the EPCIS repository and master data that describe it. The entry point of every trace-back."
    },
    {
      "name": "epcis",
      "description": "EPCIS 2.0 query interface."
    },
    {
      "name": "masterdata",
      "description": "GS1 Web Vocabulary descriptions of the parties, locations and products that events reference."
    }
  ],
  "paths": {
    "/417/{pgln}": {
      "get": {
        "tags": [
          "digitallink"
        ],
        "summary": "Links for a party (PGLN).",
        "description": "Resolves a trading party to its EPCIS query interface and its master data. Digital Link 1.1.3 onwards requires the numeric application identifier in the path; the alphabetic form is not allowed.",
        "operationId": "resolveParty",
        "parameters": [
          {
            "$ref": "#/components/parameters/PGLN"
          },
          {
            "$ref": "#/components/parameters/LinkType"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200DigitalLinks"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/414/{gln}": {
      "get": {
        "tags": [
          "digitallink"
        ],
        "summary": "Links for a location (GLN).",
        "description": "Resolves a location to its EPCIS query interface and its master data.",
        "operationId": "resolveLocation",
        "parameters": [
          {
            "$ref": "#/components/parameters/GLN"
          },
          {
            "$ref": "#/components/parameters/LinkType"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200DigitalLinks"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/01/{gtin}": {
      "get": {
        "tags": [
          "digitallink"
        ],
        "summary": "Links for a trade item (GTIN).",
        "description": "Resolves a trade item to its EPCIS query interface and its master data.",
        "operationId": "resolveTradeItem",
        "parameters": [
          {
            "$ref": "#/components/parameters/GTIN"
          },
          {
            "$ref": "#/components/parameters/LinkType"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200DigitalLinks"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/00/{sscc}": {
      "get": {
        "tags": [
          "digitallink"
        ],
        "summary": "Links for a logistic unit (SSCC).",
        "description": "Resolves a logistic unit to its EPCIS query interface. An SSCC has no master data.",
        "operationId": "resolveSSCC",
        "parameters": [
          {
            "$ref": "#/components/parameters/SSCC"
          },
          {
            "$ref": "#/components/parameters/LinkType"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200DigitalLinks"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/01/{gtin}/10/{lot}": {
      "get": {
        "tags": [
          "digitallink"
        ],
        "summary": "Links for a lot-level EPC (GTIN + lot).",
        "description": "Resolves a lot to its EPCIS query interface. Master data belongs to the trade item, at `/01/{gtin}`. This is the identifier form most GDST events carry, seafood being traced by lot.",
        "operationId": "resolveEPCClass",
        "parameters": [
          {
            "$ref": "#/components/parameters/GTIN"
          },
          {
            "$ref": "#/components/parameters/Lot"
          },
          {
            "$ref": "#/components/parameters/LinkType"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200DigitalLinks"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/01/{gtin}/21/{serial}": {
      "get": {
        "tags": [
          "digitallink"
        ],
        "summary": "Links for an instance-level EPC (GTIN + serial).",
        "description": "Resolves a serialized instance to its EPCIS query interface. Master data belongs to the trade item, at `/01/{gtin}`.",
        "operationId": "resolveEPCInstance",
        "parameters": [
          {
            "$ref": "#/components/parameters/GTIN"
          },
          {
            "$ref": "#/components/parameters/Serial"
          },
          {
            "$ref": "#/components/parameters/LinkType"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200DigitalLinks"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/events": {
      "get": {
        "tags": [
          "epcis"
        ],
        "summary": "Query EPCIS events.",
        "description": "Returns the events matching the supplied filters, as an EPCIS Query Document in EPCIS 2.0 JSON-LD.\n\nThis is the only EPCIS method GDST requires, and a conforming server must support all nine query parameters below, whether they arrive in the request URL or in a named query.\n\nEvents the caller is not authorised to see are withheld rather than failing the request, so a `200` with an empty `eventList` is valid. A query too broad to execute may be refused with `413`.\n\nTrace-back is performed by the client: query an EPC, collect the input and child EPCs of the returned events, query again. `EQ_transformationID` keeps that walk intact across transformations recorded as more than one event.",
        "operationId": "getEvents",
        "parameters": [
          {
            "$ref": "#/components/parameters/GS1-EPCIS-Version"
          },
          {
            "$ref": "#/components/parameters/GS1-EPCIS-Min"
          },
          {
            "$ref": "#/components/parameters/GS1-EPCIS-Max"
          },
          {
            "$ref": "#/components/parameters/GS1-CBV-Version"
          },
          {
            "$ref": "#/components/parameters/GS1-Extensions"
          },
          {
            "$ref": "#/components/parameters/GE_eventTime"
          },
          {
            "$ref": "#/components/parameters/LT_eventTime"
          },
          {
            "$ref": "#/components/parameters/GE_recordTime"
          },
          {
            "$ref": "#/components/parameters/LT_recordTime"
          },
          {
            "$ref": "#/components/parameters/MATCH_anyEPC"
          },
          {
            "$ref": "#/components/parameters/MATCH_anyEPCClass"
          },
          {
            "$ref": "#/components/parameters/EQ_bizStep"
          },
          {
            "$ref": "#/components/parameters/EQ_transformationID"
          },
          {
            "$ref": "#/components/parameters/EQ_bizLocation"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200EPCISQueryDocument"
          },
          "413": {
            "$ref": "#/components/responses/413QueryTooComplex"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/masterdata/{type}/{identifier}": {
      "get": {
        "tags": [
          "masterdata"
        ],
        "summary": "Master data for a party, location or product.",
        "description": "Returns the GS1 Web Vocabulary description of an identifier referenced by an event.\n\nReached by following the `gs1:masterData` link from the resolver, so its URL is chosen by the implementation and must not be hard-coded; the path here is a convention. What is required is the payload: `gs1:Organization`, `gs1:Place` or `gs1:Product`, in GS1 Web Vocabulary JSON-LD. A location must carry at least one of `address`, `geo` or `geoFence`.",
        "operationId": "getMasterData",
        "parameters": [
          {
            "$ref": "#/components/parameters/MasterDataType"
          },
          {
            "$ref": "#/components/parameters/MasterDataIdentifier"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200MasterData"
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Two parties exchange API keys bilaterally to access each other's query interface. Support for this header is mandatory; another scheme may be used instead where both sides prefer it. Key management is the sender's business — the standard only fixes where the key goes. Public data may need no authentication at all."
      }
    },
    "parameters": {
      "PGLN": {
        "in": "path",
        "name": "pgln",
        "required": true,
        "description": "Party GLN. May be the GS1 form or a GDST URN.",
        "schema": {
          "type": "string"
        },
        "example": "0614141123452"
      },
      "GLN": {
        "in": "path",
        "name": "gln",
        "required": true,
        "description": "Location GLN. May be the GS1 form or a GDST URN.",
        "schema": {
          "type": "string"
        },
        "example": "0614141123452"
      },
      "GTIN": {
        "in": "path",
        "name": "gtin",
        "required": true,
        "description": "GTIN. May be the GS1 form or a GDST URN.",
        "schema": {
          "type": "string"
        },
        "example": "10614141123452"
      },
      "SSCC": {
        "in": "path",
        "name": "sscc",
        "required": true,
        "description": "SSCC. May be the GS1 form or a GDST URN.",
        "schema": {
          "type": "string"
        },
        "example": "106141412345678908"
      },
      "Lot": {
        "in": "path",
        "name": "lot",
        "required": true,
        "description": "Lot or batch number.",
        "schema": {
          "type": "string"
        },
        "example": "LOT-2026-0042"
      },
      "Serial": {
        "in": "path",
        "name": "serial",
        "required": true,
        "description": "Serial number.",
        "schema": {
          "type": "string"
        },
        "example": "10000000001"
      },
      "LinkType": {
        "in": "query",
        "name": "linkType",
        "required": false,
        "description": "Restricts the response to links of this type. GDST requires `gs1:epcis` and `gs1:masterData`. `linkset` returns every link in RFC 9264 linkset form, where each relation is keyed by its full URI (`https://ref.gs1.org/voc/epcis`) rather than the compact form used here.",
        "schema": {
          "type": "string",
          "enum": [
            "gs1:epcis",
            "gs1:masterData",
            "linkset",
            "all"
          ]
        }
      },
      "MasterDataType": {
        "in": "path",
        "name": "type",
        "required": true,
        "schema": {
          "type": "string",
          "enum": [
            "product",
            "location",
            "party"
          ]
        }
      },
      "MasterDataIdentifier": {
        "in": "path",
        "name": "identifier",
        "required": true,
        "description": "GTIN for `product`, GLN for `location`, PGLN for `party`.",
        "schema": {
          "type": "string"
        }
      },
      "GS1-EPCIS-Version": {
        "in": "header",
        "name": "GS1-EPCIS-Version",
        "required": false,
        "description": "EPCIS version of the request.",
        "schema": {
          "type": "string",
          "const": "2.0"
        }
      },
      "GS1-EPCIS-Min": {
        "in": "header",
        "name": "GS1-EPCIS-Min",
        "required": false,
        "description": "Lowest EPCIS version accepted in the response.",
        "schema": {
          "type": "string",
          "default": "2.0"
        }
      },
      "GS1-EPCIS-Max": {
        "in": "header",
        "name": "GS1-EPCIS-Max",
        "required": false,
        "description": "Highest EPCIS version accepted in the response.",
        "schema": {
          "type": "string",
          "default": "2.0"
        }
      },
      "GS1-CBV-Version": {
        "in": "header",
        "name": "GS1-CBV-Version",
        "required": false,
        "description": "Core Business Vocabulary version.",
        "schema": {
          "type": "string",
          "const": "2.0"
        }
      },
      "GS1-Extensions": {
        "in": "header",
        "name": "GS1-Extensions",
        "required": false,
        "description": "Namespace prefix bindings for extension fields. GDST module payloads bind `gdst=https://traceability-dialogue.org/epcis`. Note that GDST master data uses a different namespace, `https://traceability-dialogue.org/vocab`, under the same prefix.",
        "schema": {
          "type": "string"
        }
      },
      "GE_eventTime": {
        "in": "query",
        "name": "GE_eventTime",
        "required": false,
        "description": "Events whose `eventTime` is greater than or equal to this instant.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "LT_eventTime": {
        "in": "query",
        "name": "LT_eventTime",
        "required": false,
        "description": "Events whose `eventTime` is strictly less than this instant.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "GE_recordTime": {
        "in": "query",
        "name": "GE_recordTime",
        "required": false,
        "description": "Events whose `recordTime` is greater than or equal to this instant. Pass the previous poll's timestamp to fetch only what has been captured since.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "LT_recordTime": {
        "in": "query",
        "name": "LT_recordTime",
        "required": false,
        "description": "Events whose `recordTime` is strictly less than this instant.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "MATCH_anyEPC": {
        "in": "query",
        "name": "MATCH_anyEPC",
        "required": false,
        "description": "Events referencing one of these instance-level EPCs in `epcList`, `childEPCs`, `parentID`, `inputEPCList` or `outputEPCList`. The filter a trace-back walks with.\n\nSerialised pipe-delimited in one parameter, with the pipe URL-encoded as `%7C` — `EQ_bizStep=shipping%7Creceiving`. Repeating the key is **not** equivalent. This matches the GS1 EPCIS 2.0 REST binding, which declares `style: pipeDelimited, explode: false` on the same parameters; that declaration is carried here as `x-style`/`x-explode` because some validators do not yet accept `style` on an OpenAPI 3.1 query parameter.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "x-style": "pipeDelimited",
        "x-explode": false,
        "example": [
          "urn:epc:id:sscc:0614141.1234567890"
        ]
      },
      "MATCH_anyEPCClass": {
        "in": "query",
        "name": "MATCH_anyEPCClass",
        "required": false,
        "description": "Events referencing one of these class-level EPCs in `quantityList`, `childQuantityList`, `inputQuantityList` or `outputQuantityList`. Lot-level trace-backs walk with this one.\n\nSerialised pipe-delimited in one parameter, with the pipe URL-encoded as `%7C` — `EQ_bizStep=shipping%7Creceiving`. Repeating the key is **not** equivalent. This matches the GS1 EPCIS 2.0 REST binding, which declares `style: pipeDelimited, explode: false` on the same parameters; that declaration is carried here as `x-style`/`x-explode` because some validators do not yet accept `style` on an OpenAPI 3.1 query parameter.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "x-style": "pipeDelimited",
        "x-explode": false,
        "example": [
          "urn:epc:class:lgtin:0614141.010614.LOT-2026-0042"
        ]
      },
      "EQ_bizStep": {
        "in": "query",
        "name": "EQ_bizStep",
        "required": false,
        "description": "Events whose `bizStep` matches one of these values. The core events use CBV steps only: `commissioning`, `destroying`, `packing`, `unpacking`, `shipping`, `receiving` — see `x-gdst-core-events`. A CBV step may be written compacted (`shipping`), as a URN (`urn:epcglobal:cbv:bizstep:shipping`) or as a web URI (`https://ref.gs1.org/cbv/BizStep-shipping`), and a server must treat the three as equivalent. No enum is declared because modules may add steps of their own.\n\nSerialised pipe-delimited in one parameter, with the pipe URL-encoded as `%7C` — `EQ_bizStep=shipping%7Creceiving`. Repeating the key is **not** equivalent. This matches the GS1 EPCIS 2.0 REST binding, which declares `style: pipeDelimited, explode: false` on the same parameters; that declaration is carried here as `x-style`/`x-explode` because some validators do not yet accept `style` on an OpenAPI 3.1 query parameter.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "x-style": "pipeDelimited",
        "x-explode": false,
        "example": [
          "shipping",
          "receiving"
        ]
      },
      "EQ_transformationID": {
        "in": "query",
        "name": "EQ_transformationID",
        "required": false,
        "description": "Events whose `transformationID` matches one of these values. A process recorded at start and at completion emits several Transformation events sharing one `transformationID`; this collects them.\n\nSerialised pipe-delimited in one parameter, with the pipe URL-encoded as `%7C` — `EQ_bizStep=shipping%7Creceiving`. Repeating the key is **not** equivalent. This matches the GS1 EPCIS 2.0 REST binding, which declares `style: pipeDelimited, explode: false` on the same parameters; that declaration is carried here as `x-style`/`x-explode` because some validators do not yet accept `style` on an OpenAPI 3.1 query parameter.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "uri"
          }
        },
        "x-style": "pipeDelimited",
        "x-explode": false
      },
      "EQ_bizLocation": {
        "in": "query",
        "name": "EQ_bizLocation",
        "required": false,
        "description": "Events whose `bizLocation` matches one of these values.\n\nSerialised pipe-delimited in one parameter, with the pipe URL-encoded as `%7C` — `EQ_bizStep=shipping%7Creceiving`. Repeating the key is **not** equivalent. This matches the GS1 EPCIS 2.0 REST binding, which declares `style: pipeDelimited, explode: false` on the same parameters; that declaration is carried here as `x-style`/`x-explode` because some validators do not yet accept `style` on an OpenAPI 3.1 query parameter.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "uri"
          }
        },
        "x-style": "pipeDelimited",
        "x-explode": false,
        "example": [
          "urn:epc:id:sgln:0614141.00888.0"
        ]
      }
    },
    "schemas": {
      "Link": {
        "type": "object",
        "description": "One resolver entry, in the flat-array form used by resolvers predating the GS1 resolver standard.",
        "required": [
          "link"
        ],
        "properties": {
          "link": {
            "type": "string",
            "format": "uri",
            "description": "For `gs1:epcis`, the base URL of the query interface; the client appends `/events`."
          },
          "title": {
            "type": "string"
          },
          "linkType": {
            "type": "string",
            "description": "Compare case-insensitively."
          },
          "mimeType": {
            "type": "string"
          },
          "authRequired": {
            "type": "boolean"
          }
        },
        "additionalProperties": true
      },
      "LinksetRelation": {
        "type": "array",
        "description": "The targets of one link relation.",
        "items": {
          "type": "object",
          "required": [
            "href"
          ],
          "properties": {
            "href": {
              "type": "string",
              "format": "uri"
            },
            "title": {
              "type": "string"
            }
          },
          "additionalProperties": true
        }
      },
      "Linkset": {
        "type": "object",
        "description": "An RFC 9264 linkset, the form the GS1 Digital Link resolver standard defines.",
        "required": [
          "linkset"
        ],
        "properties": {
          "linkset": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "anchor": {
                  "type": "string",
                  "description": "The Digital Link URI these links describe."
                },
                "https://ref.gs1.org/voc/epcis": {
                  "$ref": "#/components/schemas/LinksetRelation"
                },
                "https://ref.gs1.org/voc/masterData": {
                  "$ref": "#/components/schemas/LinksetRelation"
                },
                "https://ref.gs1.org/voc/defaultLink": {
                  "$ref": "#/components/schemas/LinksetRelation"
                }
              },
              "additionalProperties": true
            }
          }
        }
      },
      "EPCISQueryDocument": {
        "description": "An EPCIS 2.0 Query Document. The core events are plain EPCIS, so the core contract is the base EPCIS 2.0 schema published by GS1; module KDE requirements layer on top of it.\n\nThe reference is absolute so that this document resolves on its own, without a copy of the EPCIS schema beside it. `docs/epcis/epcis_schema.json` in this repository is byte-identical to it.",
        "$ref": "https://ref.gs1.org/standards/epcis/epcis-json-schema.json#/definitions/epcisQueryDocument"
      },
      "LanguageString": {
        "type": "object",
        "required": [
          "@value"
        ],
        "properties": {
          "@language": {
            "type": "string",
            "examples": [
              "en-US"
            ]
          },
          "@value": {
            "type": "string"
          }
        }
      },
      "MasterDataContext": {
        "description": "JSON-LD context of a master data element.",
        "oneOf": [
          {
            "type": "object"
          },
          {
            "type": "string"
          },
          {
            "type": "array"
          }
        ],
        "examples": [
          {
            "cbvmda": "urn:epcglobal:cbvmda:mda",
            "xsd": "http://www.w3.org/2001/XMLSchema#",
            "gs1": "http://gs1.org/voc/",
            "@vocab": "http://gs1.org/voc/",
            "gdst": "https://traceability-dialogue.org/vocab"
          }
        ]
      },
      "PostalAddress": {
        "type": "object",
        "properties": {
          "@type": {
            "type": "string",
            "const": "gs1:PostalAddress"
          },
          "streetAddress": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageString"
            },
            "x-kde-name": "streetAddressOne"
          },
          "streetAddressTwo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageString"
            },
            "x-kde-name": "streetAddressTwo"
          },
          "addressLocality": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageString"
            },
            "description": "City.",
            "x-kde-name": "city"
          },
          "addressRegion": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageString"
            },
            "description": "State or province.",
            "x-kde-name": "state"
          },
          "postalCode": {
            "type": "string",
            "x-kde-name": "postalCode"
          },
          "countryCode": {
            "type": "string",
            "description": "Two-letter ISO country code.",
            "examples": [
              "US"
            ],
            "x-kde-name": "countryCode"
          }
        },
        "additionalProperties": true,
        "description": "\n\nEach KDE has two names: the CBV master data attribute name, used in EPCIS XML master data and in the GDST KDE tables, and the GS1 Web Vocabulary name, used in JSON-LD. Property keys here are the Web Vocabulary names, because that is what travels on the wire; `x-kde-name` gives the CBV name for each, so this document can be read against the GDST KDE tables."
      },
      "GeoCoordinates": {
        "type": "object",
        "properties": {
          "@type": {
            "type": "string",
            "const": "gs1:GeoCoordinates"
          },
          "latitude": {
            "description": "Decimal degrees, as an xsd:float typed value or a plain number."
          },
          "longitude": {
            "description": "Decimal degrees, as an xsd:float typed value or a plain number."
          }
        },
        "additionalProperties": true
      },
      "PartyMasterData": {
        "type": "object",
        "description": "A trading partner.\n\nEach KDE has two names: the CBV master data attribute name, used in EPCIS XML master data and in the GDST KDE tables, and the GS1 Web Vocabulary name, used in JSON-LD. Property keys here are the Web Vocabulary names, because that is what travels on the wire; `x-kde-name` gives the CBV name for each, so this document can be read against the GDST KDE tables.",
        "required": [
          "@type",
          "globalLocationNumber"
        ],
        "properties": {
          "@context": {
            "$ref": "#/components/schemas/MasterDataContext"
          },
          "@type": {
            "type": "string",
            "const": "gs1:Organization"
          },
          "globalLocationNumber": {
            "type": "string",
            "examples": [
              "urn:gdst:example.org:party:solution.fisherman"
            ],
            "x-kde-name": "gln"
          },
          "organizationName": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageString"
            },
            "x-kde-name": "name"
          }
        },
        "additionalProperties": true
      },
      "LocationMasterData": {
        "type": "object",
        "description": "A physical facility or node. Must carry at least one of `address`, `geo` or `geoFence`: a vessel or a fishing ground is better described by a point or an area than by a postal address.\n\nEach KDE has two names: the CBV master data attribute name, used in EPCIS XML master data and in the GDST KDE tables, and the GS1 Web Vocabulary name, used in JSON-LD. Property keys here are the Web Vocabulary names, because that is what travels on the wire; `x-kde-name` gives the CBV name for each, so this document can be read against the GDST KDE tables.\n\nClassifications (`gdst:productClassification`, `gdst:locationClassification`) are GDST extension attributes on the master data element, not core EPCIS/CBV attributes. They let data be filtered by what a product is or what kind of place a location is — \"all wild-caught seafood\", \"all vessels\".",
        "required": [
          "@type",
          "globalLocationNumber"
        ],
        "anyOf": [
          {
            "required": [
              "address"
            ],
            "properties": {
              "address": {
                "$ref": "#/components/schemas/PostalAddress"
              }
            }
          },
          {
            "required": [
              "geo"
            ],
            "properties": {
              "geo": {
                "$ref": "#/components/schemas/GeoCoordinates"
              }
            }
          },
          {
            "required": [
              "geoFence"
            ],
            "properties": {
              "geoFence": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/GeoCoordinates"
                }
              }
            }
          }
        ],
        "properties": {
          "@context": {
            "$ref": "#/components/schemas/MasterDataContext"
          },
          "@type": {
            "type": "string",
            "const": "gs1:Place"
          },
          "globalLocationNumber": {
            "type": "string",
            "examples": [
              "urn:gdst:example.org:location:loc:solution.processorplant"
            ],
            "x-kde-name": "gln"
          },
          "name": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageString"
            },
            "x-kde-name": "name"
          },
          "address": {
            "$ref": "#/components/schemas/PostalAddress"
          },
          "geo": {
            "$ref": "#/components/schemas/GeoCoordinates",
            "x-kde-name": "geoLocation"
          },
          "geoFence": {
            "type": "array",
            "description": "Coordinates forming the polygon of the site boundary.",
            "items": {
              "$ref": "#/components/schemas/GeoCoordinates"
            },
            "x-kde-name": "geoFence"
          },
          "gdst:locationClassification": {
            "type": "array",
            "description": "The category of the location. **One value per location** — where a facility serves several purposes, use its primary operational role.",
            "maxItems": 1,
            "items": {
              "$ref": "#/components/schemas/Classification"
            },
            "x-gdst-values": [
              {
                "value": "Vessel",
                "description": "A watercraft used in fishing, transport or at-sea processing. Includes fishing, tender, carrier and reefer vessels."
              },
              {
                "value": "Land Facility",
                "description": "A stationary, land-based facility. Includes processing plants, cold storage, hatcheries, farms, distribution centres and ports."
              }
            ],
            "examples": [
              [
                {
                  "type": "GDST",
                  "value": "Vessel"
                }
              ]
            ]
          }
        },
        "additionalProperties": true
      },
      "ProductMasterData": {
        "type": "object",
        "description": "A trade item. Lots and serialized instances in events belong to the product identified here.\n\nEach KDE has two names: the CBV master data attribute name, used in EPCIS XML master data and in the GDST KDE tables, and the GS1 Web Vocabulary name, used in JSON-LD. Property keys here are the Web Vocabulary names, because that is what travels on the wire; `x-kde-name` gives the CBV name for each, so this document can be read against the GDST KDE tables.\n\nClassifications (`gdst:productClassification`, `gdst:locationClassification`) are GDST extension attributes on the master data element, not core EPCIS/CBV attributes. They let data be filtered by what a product is or what kind of place a location is — \"all wild-caught seafood\", \"all vessels\".",
        "required": [
          "@type",
          "gtin"
        ],
        "properties": {
          "@context": {
            "$ref": "#/components/schemas/MasterDataContext"
          },
          "@type": {
            "type": "string",
            "const": "gs1:Product"
          },
          "gtin": {
            "type": "string",
            "examples": [
              "urn:gdst:example.org:product:class:solution.wildfish"
            ],
            "x-kde-name": "gtin"
          },
          "productName": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageString"
            },
            "x-kde-name": "descriptionShort"
          },
          "gdst:productClassification": {
            "type": "array",
            "description": "What the trade item is. **Additive**: a product may carry several values, which together form a composite description — Processed + WildCaught + Seafood reads as \"processed wild-caught seafood\".",
            "items": {
              "$ref": "#/components/schemas/Classification"
            },
            "x-gdst-values": [
              {
                "value": "Processed",
                "description": "Has undergone processing or transformation — filleting, canning, freezing."
              },
              {
                "value": "Seafood",
                "description": "Intended for human consumption as seafood."
              },
              {
                "value": "WildCaught",
                "description": "Originates from wild capture fisheries."
              },
              {
                "value": "Farmed",
                "description": "Originates from aquaculture or farming operations."
              },
              {
                "value": "Feed",
                "description": "Intended for use as animal feed or feed ingredients — fishmeal, fish oil."
              },
              {
                "value": "Developing",
                "description": "In a developing life stage — eggs, larvae, fry, juveniles, smolt."
              },
              {
                "value": "Mature",
                "description": "In a mature or market-ready life stage."
              },
              {
                "value": "Live",
                "description": "Live at the point of trade — live shellfish, live fish for restocking."
              }
            ],
            "examples": [
              [
                {
                  "type": "GDST",
                  "value": "Processed"
                },
                {
                  "type": "GDST",
                  "value": "WildCaught"
                },
                {
                  "type": "GDST",
                  "value": "Seafood"
                }
              ]
            ]
          }
        },
        "additionalProperties": true
      },
      "ProblemResponseBody": {
        "type": "object",
        "description": "RFC 7807 problem details, as EPCIS 2.0 uses throughout.",
        "properties": {
          "type": {
            "type": "string",
            "examples": [
              "epcisException:ValidationException"
            ]
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          }
        }
      },
      "Classification": {
        "type": "object",
        "description": "A GDST classification value. The same shape is used for products and for locations.\n\nValues follow the capitalisation the standard defines (`Seafood`, `WildCaught`). Some GDST example data uses lower case; the standard's form is the correct one. Both lists are extensible through the GDST governance process, so no closed enum is declared here — the current values are listed under `x-gdst-values` on each attribute.",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "GDST"
          },
          "value": {
            "type": "string",
            "examples": [
              "WildCaught"
            ]
          }
        }
      }
    },
    "responses": {
      "200DigitalLinks": {
        "description": "The links registered for the identifier; an empty result where none match the requested type, not a `404`. Two shapes circulate: the RFC 9264 linkset that the GS1 resolver standard defines, and the flat array returned by older resolvers. A client should accept either.",
        "content": {
          "application/json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/Linkset"
                },
                {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Link"
                  }
                }
              ]
            },
            "examples": {
              "linkset": {
                "summary": "Linkset form",
                "value": {
                  "linkset": [
                    {
                      "anchor": "https://resolver.example.org/01/urn:gdst:example.org:product:class:system.processedfish",
                      "https://ref.gs1.org/voc/epcis": [
                        {
                          "href": "https://resolver.example.org/epcis",
                          "title": "EPCIS Repository"
                        }
                      ],
                      "https://ref.gs1.org/voc/masterData": [
                        {
                          "href": "https://resolver.example.org/masterdata/product/urn:gdst:example.org:product:class:system.processedfish",
                          "title": "Master Data"
                        }
                      ]
                    }
                  ]
                }
              },
              "flatArray": {
                "summary": "Flat array form",
                "value": [
                  {
                    "link": "https://resolver.example.org/epcis",
                    "linkType": "gs1:epcis",
                    "title": "EPCIS Repository",
                    "authRequired": true
                  }
                ]
              }
            }
          }
        }
      },
      "200EPCISQueryDocument": {
        "description": "The matching events. Events the caller is not authorised to see are omitted.",
        "headers": {
          "GS1-EPCIS-Version": {
            "description": "EPCIS version used.",
            "schema": {
              "type": "string"
            }
          },
          "GS1-CBV-Version": {
            "description": "CBV version used.",
            "schema": {
              "type": "string"
            }
          },
          "GS1-Extensions": {
            "description": "Namespace bindings for extension fields in the response.",
            "schema": {
              "type": "string"
            }
          }
        },
        "content": {
          "application/ld+json": {
            "schema": {
              "$ref": "#/components/schemas/EPCISQueryDocument"
            },
            "example": {
              "@context": [
                "https://ref.gs1.org/standards/epcis/epcis-context.jsonld"
              ],
              "type": "EPCISQueryDocument",
              "schemaVersion": "2.0",
              "creationDate": "2026-06-12T21:30:38.749Z",
              "epcisBody": {
                "queryResults": {
                  "queryName": "SimpleEventQuery",
                  "resultsBody": {
                    "eventList": [
                      {
                        "type": "ObjectEvent",
                        "eventTime": "2026-03-15T00:30:38.749Z",
                        "eventTimeZoneOffset": "+00:00",
                        "eventID": "urn:uuid:526b0653-c19e-4044-b87f-25c1720c35c2",
                        "epcList": [],
                        "action": "OBSERVE",
                        "bizStep": "shipping",
                        "disposition": "in_transit",
                        "bizLocation": {
                          "id": "urn:gdst:example.org:location:loc:system.vessel1"
                        },
                        "quantityList": [
                          {
                            "epcClass": "urn:gdst:example.org:product:lot:class:system.wildfish.lot2",
                            "quantity": 9876.0,
                            "uom": "KGM"
                          }
                        ],
                        "sourceList": [
                          {
                            "type": "location",
                            "source": "urn:gdst:example.org:location:loc:system.vessel1"
                          }
                        ],
                        "destinationList": [
                          {
                            "type": "location",
                            "destination": "urn:gdst:example.org:location:loc:system.vessel2"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "200MasterData": {
        "description": "The master data element, in GS1 Web Vocabulary JSON-LD.",
        "content": {
          "application/ld+json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/PartyMasterData"
                },
                {
                  "$ref": "#/components/schemas/LocationMasterData"
                },
                {
                  "$ref": "#/components/schemas/ProductMasterData"
                }
              ],
              "discriminator": {
                "propertyName": "@type",
                "mapping": {
                  "gs1:Organization": "#/components/schemas/PartyMasterData",
                  "gs1:Place": "#/components/schemas/LocationMasterData",
                  "gs1:Product": "#/components/schemas/ProductMasterData"
                }
              }
            }
          }
        }
      },
      "413QueryTooComplex": {
        "description": "The query is too broad to execute — filtering only by event type, for example. Narrow it with an EPC, a time range or a business location.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemResponseBody"
            }
          }
        }
      },
      "Problem": {
        "description": "An error, as RFC 7807 problem details. `400` malformed request, `401` missing or unrecognised credentials, `403` credentials valid but not for this resource, `404` unknown identifier, `406` unsatisfiable `Accept` or version range, `5XX` server failure.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemResponseBody"
            }
          }
        }
      }
    }
  }
}
