{
 "openapi": "3.1.0",
 "info": {
  "title": "GLS/NXT OOH Platform Integration REST API",
  "version": "1.12.0",
  "description": "Endpoints carriers call. The guides explain concepts, flows and statuses."
 },
 "servers": [
  {
   "url": "https://api.staging.glsnxt.com/ooh/carrier-connector/v1",
   "description": "Staging"
  },
  {
   "url": "https://api.glsnxt.com/ooh/carrier-connector/v1",
   "description": "Production"
  }
 ],
 "security": [
  {
   "ApiKeyAuth": []
  }
 ],
 "tags": [
  {
   "name": "Locker API",
   "description": "The Locker API endpoints provide comprehensive management of lockers, including their creation, updating, and retrieval. These endpoints support:\n- **Locker Creation**: Set up new lockers with necessary details such as location, internal carrier IDs, and specific locker features.\n- **Locker Information Retrieval**: Access detailed information about lockers, including their status and location.\n- **Locker Updates**: Update existing locker details to reflect changes in status or configuration.\n\n**Key Features:**\n- **Flexible Locker Management**: Create and update lockers to keep information current and accurate.\n- **Detailed Location Data**: Access geographic and logistical details of each locker.\n- **Compartment Management**: Manage the availability and allocation of compartments within lockers.\n"
  },
  {
   "name": "Locker Group API",
   "description": "The Locker Group API endpoints let carriers organise their lockers into named, typed groups. These endpoints support:\n- **Type Catalog**: Retrieve the global catalog of available locker group types.\n- **Group Management**: Create, rename, retrieve, list, and delete locker groups.\n- **Locker Assignment**: Assign and remove the carrier's lockers to and from a group.\n\n**Key Features:**\n- **Typed Groups**: Each group has a type from the shared catalog; a locker may belong to at most one group per type key.\n- **Carrier-scoped**: Groups and their lockers are scoped to the calling carrier.\n"
  },
  {
   "name": "Network API",
   "description": "The Network API endpoints provide management of locker networks, enabling carriers to share lockers between network owners and tenants. These endpoints support:\n- **Network Listing**: View all networks where the carrier is the owner or tenant.\n- **Network Locker Management**: Add, remove, and update lockers within a network.\n- **Paginated Locker Retrieval**: Retrieve lockers in a network with filtering and pagination.\n\n**Key Features:**\n- **Locker Sharing**: Share lockers between carriers through networks.\n- **Status Management**: Track and update locker status within networks (e.g., PENDING, ACCEPTED, DECLINED).\n- **Carrier Details**: Optionally update carrier-specific details when managing network lockers.\n"
  },
  {
   "name": "Parcel API",
   "description": "The Parcel API endpoints are focused on the management of the parcel bookings. It allows for Carrier to publish parcel data for respective locker booking creation, the retrieval of parcel information and cancellation of parcel bookings.\n- **Parcel Data Publishing**: Publish parcel data from the Carrier into the OOH Platform, enabling carriers to trigger locker bookings or pre-checks at the appropriate time.\n- **Parcel Information Retrieval**: Fetch details of parcels, including status, and event history.\n- **Parcel Cancellation**: Cancel parcel booking for parcels that are no longer to be delivered into the locker.\n\n**Key Features:**\n- **Real-time Parcel Bookings**: Push real-time parcel data to the OOH Platform to perform bookings at any time.\n- **Comprehensive Parcel Data**: Retrieve detailed information on parcel booking status and history.\n- **Cancellation Flexibility**: Cancel undelivered parcels to manage logistics effectively.\n"
  }
 ],
 "paths": {
  "/lockers": {
   "post": {
    "tags": [
     "Locker API"
    ],
    "summary": "Create a new locker",
    "description": "Create a new locker with the specified details for the carrier, provider, location, and features.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "createLocker",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/create_input"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Locker created successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/locker_response"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "409": {
      "description": "Can not create locker for the same provider and location",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Conflict",
         "message": "Carrier locker already exists"
        }
       }
      }
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "get": {
    "tags": [
     "Locker API"
    ],
    "summary": "Get a list of lockers",
    "description": "Retrieve a list of lockers with optional filters such as location, status, carrier, and provider.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "listLockers",
    "parameters": [
     {
      "name": "providerName",
      "in": "query",
      "required": false,
      "description": "Filter lockers by provider name.",
      "schema": {
       "type": "string",
       "example": "BLOQ"
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Filter lockers by status.",
      "schema": {
       "$ref": "#/components/schemas/status",
       "example": "ACTIVE"
      }
     },
     {
      "name": "city",
      "in": "query",
      "required": false,
      "description": "Filter lockers by city.",
      "schema": {
       "type": "string",
       "example": "Berlin"
      }
     },
     {
      "name": "countryCode",
      "in": "query",
      "required": false,
      "description": "Filter lockers by country code (ISO 3166-1 alpha-2).",
      "schema": {
       "type": "string",
       "example": "DE"
      }
     },
     {
      "name": "compartmentSize",
      "in": "query",
      "required": false,
      "description": "Filter lockers by the size of compartments available.",
      "example": "MEDIUM",
      "schema": {
       "$ref": "#/components/schemas/compartment_size"
      }
     },
     {
      "name": "ownedBy",
      "in": "query",
      "required": false,
      "description": "When `true`, return only the lockers that the carrier owns.",
      "schema": {
       "type": "boolean",
       "default": false,
       "example": true
      }
     }
    ],
    "responses": {
     "200": {
      "description": "List of lockers retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/locker_response"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/lockers/{uid}": {
   "patch": {
    "tags": [
     "Locker API"
    ],
    "summary": "Update a locker",
    "description": "Update the details of an existing locker, including carrier details, provider details, location, and features.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "updateLocker",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The OOH Platform UID for the locker.",
      "schema": {
       "type": "string",
       "example": "426614174000"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/update_input"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Locker updated successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/locker_response"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "409": {
      "description": "Another locker of the carrier already has this carrier locker ID.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Conflict",
         "message": "carrierLockerId is already assigned to another non-decommissioned locker for this carrier."
        }
       }
      }
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/lockers/by-uid": {
   "get": {
    "tags": [
     "Locker API"
    ],
    "summary": "Get lockers by UIDs",
    "description": "Retrieve one or more lockers by their UIDs in a single request.\n\n- The `ids` query parameter accepts a comma-separated list of locker UIDs (e.g. `ids=10000001,10000002`).\n- Maximum 10 UIDs per request — exceeding the limit returns 400.\n- Returns 200 with a JSON array when at least one numeric UID is present; non-existent UIDs, UIDs belonging to other carriers, and non-numeric tokens within a mixed input are silently omitted.\n- Returns 400 when `ids` is missing, blank, or contains no numeric tokens.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "getLockersByUids",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "required": true,
      "description": "Comma-separated locker UIDs. Up to 10 numeric UIDs per request. Non-numeric tokens within a mixed input are silently dropped before the cap check; an input with no numeric tokens at all returns 400.",
      "schema": {
       "type": "string",
       "minLength": 1,
       "maxLength": 200,
       "example": "10000001,10000002"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "List of matching lockers retrieved successfully. Missing or inaccessible UIDs are silently omitted.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/locker_response"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/lockers/by-carrier-locker-id": {
   "get": {
    "tags": [
     "Locker API"
    ],
    "summary": "Get lockers by carrier locker ids",
    "description": "Retrieve one or more lockers by their carrier locker ids in a single request.\n\n- The `ids` query parameter accepts a comma-separated list of carrier locker ids (e.g. `ids=DE46677,DE12345`).\n- Carrier locker ids are alphanumeric and kept as-is — this is exactly the case `/lockers/by-uid` cannot handle.\n- Maximum 10 ids per request — exceeding the limit returns 400.\n- Returns 200 with a JSON array; non-existent ids and ids belonging to other carriers are silently omitted.\n- Returns 400 when `ids` is missing, blank, or contains no non-empty tokens.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "getLockersByCarrierLockerIds",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "required": true,
      "description": "Comma-separated carrier locker ids. Up to 10 ids per request. Empty tokens are dropped before the cap check; an input with no non-empty tokens returns 400.",
      "schema": {
       "type": "string",
       "minLength": 1,
       "maxLength": 200,
       "example": "DE46677,DE12345"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "List of matching lockers retrieved successfully. Missing or inaccessible carrier locker ids are silently omitted.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/locker_response"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/lockers/providers": {
   "get": {
    "tags": [
     "Locker API"
    ],
    "summary": "Get a list of existing locker model and locker version pairs for provider",
    "description": "Retrieve a list of existing locker model and locker version pairs for each provider.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "listLockerProviders",
    "responses": {
     "200": {
      "description": "List of existing locker model and locker version pairs for each provider retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "allOf": [
           {
            "type": "object",
            "properties": {
             "providerName": {
              "type": "string",
              "description": "The name of the locker provider."
             },
             "lockerModel": {
              "type": "string",
              "description": "The model of the locker provided by the provider."
             },
             "lockerVersion": {
              "type": "string",
              "description": "The version of the locker model provided by the provider."
             },
             "providerUid": {
              "type": "string",
              "description": "The unique identifier of the provider on the GLS/NXT system."
             }
            }
           }
          ]
         }
        },
        "example": [
         {
          "providerName": "KEBA",
          "lockerModel": "Model 1",
          "lockerVersion": "v2.1",
          "providerUid": "1103459297"
         },
         {
          "providerName": "KEBA",
          "lockerModel": "Model 1",
          "lockerVersion": "v2.2",
          "providerUid": "1103459297"
         },
         {
          "providerName": "KEBA",
          "lockerModel": "Model 2",
          "lockerVersion": "v1.0",
          "providerUid": "1103459297"
         },
         {
          "providerName": "MYFLEXBOX",
          "lockerModel": "Model 23",
          "lockerVersion": "v1.5",
          "providerUid": "1203659298"
         }
        ]
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/lockers/status": {
   "patch": {
    "tags": [
     "Locker API"
    ],
    "summary": "Update Locker Status",
    "description": "Update the status of an existing locker.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "updateLockerStatus",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/update_status"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Locker status updated successfully.",
      "content": {}
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "409": {
      "description": "The request conflicts with the current state of the target resource",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Conflict",
         "message": "The locker status cannot be updated due to a conflicting state"
        }
       }
      }
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/locker-groups/types": {
   "get": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Get available locker group types",
    "description": "Returns the global catalog of locker group types that can be used to create locker groups.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "listLockerGroupTypes",
    "responses": {
     "200": {
      "description": "List of locker group types retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/locker_group_type"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/locker-groups": {
   "get": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Get a list of locker groups",
    "description": "Returns the carrier's locker groups, optionally filtered by type key and name.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "listLockerGroups",
    "parameters": [
     {
      "name": "lockerGroupTypeKeys",
      "in": "query",
      "required": false,
      "description": "Filter locker groups by one or more type keys.",
      "schema": {
       "type": "array",
       "items": {
        "type": "string"
       }
      },
      "example": [
       "DEPOT"
      ]
     },
     {
      "name": "lockerGroupName",
      "in": "query",
      "required": false,
      "description": "Filter locker groups by name.",
      "schema": {
       "type": "string"
      },
      "example": "Berlin Central"
     }
    ],
    "responses": {
     "200": {
      "description": "List of locker groups retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/locker_group"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "post": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Create a locker group",
    "description": "Creates a new locker group for the carrier.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "createLockerGroup",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/locker_group_create_request"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Locker group created successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/locker_group"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "409": {
      "description": "The carrier already has a locker group with this type key and name.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Conflict",
         "message": "Locker group already exists"
        }
       }
      }
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/locker-groups/{uid}": {
   "get": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Get a specific locker group",
    "description": "Retrieve details of a specific locker group by its unique identifier.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "getLockerGroup",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the locker group.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 6838265090
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Locker group retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/locker_group"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "description": "The locker group does not exist or belongs to another carrier. The response has no body."
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "patch": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Update a locker group",
    "description": "Updates the name of an existing locker group.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "updateLockerGroup",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the locker group.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 6838265090
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/locker_group_update_request"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Locker group updated successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/locker_group"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "delete": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Delete a locker group",
    "description": "Deletes a locker group owned by the carrier.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "deleteLockerGroup",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the locker group.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 6838265090
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Locker group deleted successfully."
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/locker-groups/{uid}/lockers": {
   "post": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Assign lockers to a locker group",
    "description": "Assigns the carrier's lockers to the locker group. A locker may belong to at most one group per type key.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "addLockerGroupLockers",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the locker group.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 6838265090
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/locker_group_add_request"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Lockers assigned to the group successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/locker_group_add_response"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "409": {
      "description": "A locker is already in another locker group of the same type.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Conflict",
         "message": "Locker already belongs to a group of the same type"
        }
       }
      }
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "delete": {
    "tags": [
     "Locker Group API"
    ],
    "summary": "Remove lockers from a locker group",
    "description": "Removes the specified lockers from the locker group.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "removeLockerGroupLockers",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the locker group.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 6838265090
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/locker_group_remove_request"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Lockers removed from the group successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/locker_group_removed_response"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/networks": {
   "get": {
    "tags": [
     "Network API"
    ],
    "summary": "Get a list of networks",
    "description": "Returns all networks where the carrier is the owner or tenant.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "listNetworks",
    "responses": {
     "200": {
      "description": "List of networks retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/network"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/networks/{uid}": {
   "get": {
    "tags": [
     "Network API"
    ],
    "summary": "Get a specific network",
    "description": "Retrieve details of a specific network by its unique identifier.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "getNetwork",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the network.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 8065713862
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Network retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/network"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "description": "The network does not exist or the carrier is neither its owner nor its tenant. The response has no body."
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "delete": {
    "tags": [
     "Network API"
    ],
    "summary": "Delete a network",
    "description": "Deletes a network. Fails if any lockers are still in ACCEPTED status.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "deleteNetwork",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the network.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 8065713862
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Network deleted successfully. The response has no body."
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "409": {
      "description": "The network still has lockers in ACCEPTED status.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Conflict",
         "message": "Network cannot be removed because lockers are still active in network"
        }
       }
      }
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/networks/{uid}/lockers": {
   "get": {
    "tags": [
     "Network API"
    ],
    "summary": "Get lockers in a network",
    "description": "Retrieve a paginated list of lockers within a network with optional filtering and sorting.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "listNetworkLockers",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the network.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 8065713862
      }
     },
     {
      "name": "networkLockerStatus",
      "in": "query",
      "required": false,
      "description": "Filter lockers by their network status.",
      "schema": {
       "type": "string",
       "example": "ACCEPTED"
      }
     },
     {
      "name": "page",
      "in": "query",
      "required": false,
      "description": "The page number to retrieve (1-based).",
      "schema": {
       "type": "integer",
       "format": "int32",
       "default": 1,
       "example": 1
      }
     },
     {
      "name": "pageSize",
      "in": "query",
      "required": false,
      "description": "The number of items per page.",
      "schema": {
       "type": "integer",
       "format": "int32",
       "default": 100,
       "example": 100
      }
     },
     {
      "name": "sortBy",
      "in": "query",
      "required": false,
      "description": "The field to sort results by.",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "sortDirection",
      "in": "query",
      "required": false,
      "description": "The sort direction.",
      "schema": {
       "type": "string",
       "default": "ASC",
       "example": "ASC"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Paginated list of network lockers retrieved successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/network_locker_page"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "post": {
    "tags": [
     "Network API"
    ],
    "summary": "Add lockers to a network",
    "description": "Adds lockers owned by the carrier to the network. Lockers not owned by the carrier are silently skipped.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "addNetworkLockers",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the network.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 8065713862
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/network_locker_add_request"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "List of newly added network lockers.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/network_locker"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   },
   "delete": {
    "tags": [
     "Network API"
    ],
    "summary": "Remove lockers from a network",
    "description": "Removes the specified lockers from the network.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "removeNetworkLockers",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the network.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 8065713862
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/network_locker_remove_request"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "List of removed network lockers.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/network_locker"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/networks/{uid}/lockers/{lockerUid}": {
   "patch": {
    "tags": [
     "Network API"
    ],
    "summary": "Update a network locker",
    "description": "Updates the status of a locker within a network, optionally including carrier details.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "updateNetworkLocker",
    "parameters": [
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the network.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 8065713862
      }
     },
     {
      "name": "lockerUid",
      "in": "path",
      "required": true,
      "description": "The unique identifier of the locker within the network.",
      "schema": {
       "type": "integer",
       "format": "int64",
       "example": 10000019
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/network_locker_patch"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Network locker updated successfully.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/network_locker"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/response_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/response_404"
     },
     "409": {
      "description": "Another locker of the carrier already has this carrier locker ID.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Conflict",
         "message": "carrierLockerId is already assigned to another non-decommissioned locker for this carrier."
        }
       }
      }
     },
     "422": {
      "description": "The network locker cannot move from its current status to the requested status.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/response_409"
        },
        "example": {
         "errorCode": "Unprocessable Entity",
         "message": "Network locker status transition not allowed from ACCEPTED to REMOVED"
        }
       }
      }
     },
     "500": {
      "$ref": "#/components/responses/response_500"
     }
    }
   }
  },
  "/parcels/data": {
   "post": {
    "tags": [
     "Parcel API"
    ],
    "summary": "Publish parcel data",
    "description": "This endpoint allows the Carriers to publish parcel data into the OOH Platform. It should be used to push parcel data at the time when the locker booking is expected to take place or to pre-check if a parcel can be accepted in the locker.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "publishParcelData",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/input_data"
       }
      }
     }
    },
    "responses": {
     "200": {
      "$ref": "#/components/responses/parcel_input_200"
     },
     "400": {
      "$ref": "#/components/responses/parcel_input_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/parcel_input_500"
     }
    }
   }
  },
  "/parcels/data/by-tenant-locker-id": {
   "post": {
    "tags": [
     "Parcel API"
    ],
    "summary": "Publish parcel data with carrier locker id",
    "description": "This endpoint is an alternative to `/parcels/data` endpoint and could be used to publish parcel data using carrierLockerId instead of lockerUid.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "publishParcelDataByTenantId",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/input_data_carrier_specific"
       }
      }
     }
    },
    "responses": {
     "200": {
      "$ref": "#/components/responses/parcel_input_200"
     },
     "400": {
      "$ref": "#/components/responses/parcel_input_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/parcel_input_500"
     }
    }
   }
  },
  "/parcels": {
   "get": {
    "tags": [
     "Parcel API"
    ],
    "summary": "Get parcels",
    "description": "Retrieve a list of parcels associated with the carrier. This endpoint allows fetching detailed information about parcels, including their status and history.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "getParcels",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "description": "Comma-separated list of parcel IDs to retrieve",
      "required": true,
      "schema": {
       "type": "string",
       "example": "12345131,G6789011,A1234511"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Parcels fetched successfully. The list is empty when the carrier has no parcel with these IDs.",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "description": "List of parcels",
         "items": {
          "$ref": "#/components/schemas/parcel_response"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/sma_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "500": {
      "$ref": "#/components/responses/sma_500"
     }
    }
   }
  },
  "/v2/parcels": {
   "get": {
    "tags": [
     "Parcel API"
    ],
    "summary": "Get parcels (v2)",
    "description": "Retrieve a paginated list of parcels associated with the carrier, filterable by locker and/or parcel IDs.\n\n- At least one of `lockerId`, `carrierLockerId` or `ids` must be provided.\n- When more than one filter is given, the result is the **intersection** of all provided filters.\n- By default this endpoint returns parcels **regardless of status** — both active bookings and completed/final parcels linked to the locker. Pass `isFinal` to narrow the result to open (`false`) or finalized (`true`) parcels.\n- The platform does not page deeper than 10000 parcels. When `(page - 1) * pageSize` is more than 10000, the response is `422`. Use more filters instead.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "getParcelsV2",
    "parameters": [
     {
      "name": "lockerId",
      "in": "query",
      "description": "The platform locker UID to filter by. At least one of `lockerId`, `carrierLockerId` or `ids` is required.",
      "required": false,
      "schema": {
       "type": "string",
       "example": "anyLockerId123"
      }
     },
     {
      "name": "carrierLockerId",
      "in": "query",
      "description": "The carrier's own locker identifier to filter by. At least one of `lockerId`, `carrierLockerId` or `ids` is required.",
      "required": false,
      "schema": {
       "type": "string",
       "example": "2760935259"
      }
     },
     {
      "name": "ids",
      "in": "query",
      "description": "Comma-separated list of parcel IDs to filter by. At least one of `lockerId`, `carrierLockerId` or `ids` is required.",
      "required": false,
      "schema": {
       "type": "string",
       "example": "12345131,G6789011,A1234511"
      }
     },
     {
      "name": "isFinal",
      "in": "query",
      "description": "Optional finality filter. When omitted, no status filter is applied (all statuses). `true` returns only finalized parcels, `false` returns only open ones. Must be lowercase `true` or `false`.",
      "required": false,
      "schema": {
       "type": "boolean",
       "example": false
      }
     },
     {
      "name": "page",
      "in": "query",
      "description": "The page number to retrieve (1-based).",
      "required": false,
      "schema": {
       "type": "integer",
       "format": "int32",
       "default": 1,
       "minimum": 1,
       "example": 1
      }
     },
     {
      "name": "pageSize",
      "in": "query",
      "description": "The number of items per page. Maximum 100.",
      "required": false,
      "schema": {
       "type": "integer",
       "format": "int32",
       "default": 30,
       "minimum": 1,
       "maximum": 100,
       "example": 30
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Parcels fetched successfully",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/parcel_page"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/sma_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "422": {
      "$ref": "#/components/responses/sma_422"
     },
     "500": {
      "$ref": "#/components/responses/sma_500"
     }
    }
   }
  },
  "/parcels/{parcelId}": {
   "patch": {
    "tags": [
     "Parcel API"
    ],
    "summary": "Cancel parcel",
    "description": "Cancel the booking of a specific parcel. Only parcels that haven’t been delivered can be cancelled. This endpoint allows carriers to manage cancellations effectively.\n\nWhen the locker provider rejects the cancellation, the response has the provider's HTTP status code and an `sma_error` body.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "cancelParcel",
    "parameters": [
     {
      "name": "parcelId",
      "in": "path",
      "description": "The parcel ID to be cancelled",
      "required": true,
      "schema": {
       "type": "string",
       "example": "1234567890"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Parcel cancelled successfully"
     },
     "400": {
      "$ref": "#/components/responses/sma_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/sma_404"
     },
     "409": {
      "$ref": "#/components/responses/sma_409"
     },
     "500": {
      "$ref": "#/components/responses/sma_500"
     },
     "default": {
      "$ref": "#/components/responses/sma_provider_error"
     }
    }
   }
  },
  "/parcels/{parcelId}/lock": {
   "patch": {
    "tags": [
     "Parcel API"
    ],
    "summary": "Lock or unlock a parcel",
    "description": "Lock or unlock a parcel in its locker compartment. Locking prevents the consignee\nfrom collecting the parcel — for example while a cash-on-delivery payment is still\npending — and unlocking releases it for collection. The carrier is identified by the\nAPI key.\n\nParcel locking must be enabled for the carrier; otherwise the response is `422`.\nWhen the locker provider rejects the request, the response has the provider's HTTP\nstatus code and an `sma_error` body.\n",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "operationId": "lockParcel",
    "parameters": [
     {
      "name": "parcelId",
      "in": "path",
      "description": "The identifier of the parcel in the carrier's system.",
      "required": true,
      "schema": {
       "type": "string",
       "example": "1234567890"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/parcel_lock_request"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Lock state updated successfully."
     },
     "400": {
      "$ref": "#/components/responses/sma_400"
     },
     "401": {
      "$ref": "#/components/responses/gateway_401"
     },
     "404": {
      "$ref": "#/components/responses/sma_404"
     },
     "422": {
      "$ref": "#/components/responses/sma_422"
     },
     "500": {
      "$ref": "#/components/responses/sma_500"
     },
     "default": {
      "$ref": "#/components/responses/sma_provider_error"
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "ApiKeyAuth": {
    "type": "apiKey",
    "name": "X-API-Key",
    "in": "header",
    "description": "API Authorization Key for API access"
   }
  },
  "schemas": {
   "status": {
    "type": "string",
    "enum": [
     "ACTIVE",
     "INACTIVE",
     "MAINTENANCE",
     "DECOMMISSIONED",
     "INITIAL",
     "PLANNED"
    ],
    "example": "ACTIVE"
   },
   "compartment_size": {
    "type": "string",
    "description": "Locker compartment size.",
    "enum": [
     "XXSMALL",
     "XSMALL",
     "SMALL",
     "XMEDIUM",
     "MEDIUM",
     "LARGE",
     "XLARGE",
     "XXLARGE",
     "ULARGE",
     "UULARGE"
    ],
    "example": "MEDIUM"
   },
   "location": {
    "type": "object",
    "description": "Details about the geographical location of the locker.",
    "properties": {
     "street": {
      "type": "string",
      "description": "The street name where the locker is located.",
      "example": "Main Street"
     },
     "streetNumber": {
      "type": "string",
      "description": "The street number of the locker location.",
      "example": "1"
     },
     "postalCode": {
      "type": "string",
      "description": "The postal code of the locker location.",
      "example": "90210"
     },
     "city": {
      "type": "string",
      "description": "The city where the locker is located.",
      "example": "Berlin"
     },
     "lon": {
      "type": "number",
      "format": "double",
      "description": "The longitude coordinate of the locker location.",
      "example": -118.2437
     },
     "lat": {
      "type": "number",
      "format": "double",
      "description": "The latitude coordinate of the locker location.",
      "example": 34.0522
     },
     "countryCode": {
      "type": "string",
      "description": "The ISO 3166-1 alpha-2 country code for the locker location.",
      "example": "DE"
     },
     "type": {
      "type": "string",
      "enum": [
       "indoor",
       "outdoor"
      ],
      "description": "Optional location type indicating whether the locker is indoors or outdoors. Omitted when unspecified.",
      "example": "indoor"
     }
    },
    "required": [
     "street",
     "postalCode",
     "city",
     "lon",
     "lat",
     "countryCode"
    ]
   },
   "features": {
    "type": "object",
    "description": "Features available in the locker.",
    "properties": {
     "hasScreen": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "Indicates if the locker has a screen.",
      "example": true
     },
     "hasPinPad": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "Indicates if the locker has a PIN pad.",
      "example": true
     },
     "hasPinBarcodeReader": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "Indicates if the locker has a barcode reader.",
      "example": false
     }
    }
   },
   "period": {
    "type": "object",
    "required": [
     "open",
     "close"
    ],
    "properties": {
     "open": {
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
      "example": "08:00",
      "description": "Local opening time (inclusive)"
     },
     "close": {
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
      "example": "20:00",
      "description": "Local closing time (exclusive)"
     }
    }
   },
   "weekly_period": {
    "type": "object",
    "required": [
     "weekday",
     "periods"
    ],
    "properties": {
     "weekday": {
      "type": "string",
      "enum": [
       "MONDAY",
       "TUESDAY",
       "WEDNESDAY",
       "THURSDAY",
       "FRIDAY",
       "SATURDAY",
       "SUNDAY"
      ]
     },
     "periods": {
      "type": "array",
      "minItems": 1,
      "items": {
       "$ref": "#/components/schemas/period"
      }
     }
    }
   },
   "exception_period": {
    "type": "object",
    "description": "A date range overriding the default weekly schedule.\n\nConditional constraint (enforced server-side, not by the generated client):\n- Exactly one of `isClosed` (set to `true`) or `schedule` MUST be present.\n  Sending both, neither, or `isClosed: false` is a contract violation.\n",
    "required": [
     "startDate",
     "endDate"
    ],
    "properties": {
     "startDate": {
      "type": "string",
      "format": "date",
      "example": "2026-12-25"
     },
     "endDate": {
      "type": "string",
      "format": "date",
      "example": "2026-12-25"
     },
     "isClosed": {
      "type": "boolean",
      "description": "Marker flag indicating the locker is fully inaccessible for this range.\nWhen present it MUST be `true`; otherwise omit the field entirely.\nMutually exclusive with `schedule`.\n"
     },
     "schedule": {
      "type": "array",
      "minItems": 1,
      "description": "Overrides for specific weekdays within the exception range.\nMutually exclusive with `isClosed` — omit this field when `isClosed` is set.\n",
      "items": {
       "$ref": "#/components/schemas/weekly_period"
      },
      "example": [
       {
        "weekday": "MONDAY",
        "periods": [
         {
          "open": "10:00",
          "close": "16:00"
         }
        ]
       }
      ]
     }
    }
   },
   "opening_hours": {
    "type": "object",
    "description": "Locker availability schedule.\n\nConditional constraints (enforced server-side, not by the generated client):\n- If `accessMode` is `SCHEDULED`, `weeklySchedule` MUST be provided and non-empty.\n- If `accessMode` is `ALWAYS`, `weeklySchedule` MUST be omitted.\n",
    "required": [
     "accessMode"
    ],
    "properties": {
     "accessMode": {
      "type": "string",
      "enum": [
       "ALWAYS",
       "SCHEDULED"
      ],
      "description": "General availability mode.\n- `ALWAYS`: locker is always accessible; `weeklySchedule` must be omitted.\n- `SCHEDULED`: locker follows `weeklySchedule` (and any `exceptions`).\n"
     },
     "weeklySchedule": {
      "type": "array",
      "description": "Default schedule per weekday. Required and non-empty when `accessMode` is `SCHEDULED`; must be omitted when `accessMode` is `ALWAYS`.",
      "minItems": 1,
      "items": {
       "$ref": "#/components/schemas/weekly_period"
      }
     },
     "exceptions": {
      "type": "array",
      "description": "Overrides for specific dates (holidays, maintenance, seasonal hours). Ignored when `accessMode` is `ALWAYS`.",
      "items": {
       "$ref": "#/components/schemas/exception_period"
      }
     }
    },
    "$defs": {
     "weekly_period": {
      "type": "object",
      "required": [
       "weekday",
       "periods"
      ],
      "properties": {
       "weekday": {
        "type": "string",
        "enum": [
         "MONDAY",
         "TUESDAY",
         "WEDNESDAY",
         "THURSDAY",
         "FRIDAY",
         "SATURDAY",
         "SUNDAY"
        ]
       },
       "periods": {
        "type": "array",
        "minItems": 1,
        "items": {
         "$ref": "#/components/schemas/period"
        }
       }
      }
     },
     "period": {
      "type": "object",
      "required": [
       "open",
       "close"
      ],
      "properties": {
       "open": {
        "type": "string",
        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
        "example": "08:00",
        "description": "Local opening time (inclusive)"
       },
       "close": {
        "type": "string",
        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
        "example": "20:00",
        "description": "Local closing time (exclusive)"
       }
      }
     },
     "exception_period": {
      "type": "object",
      "description": "A date range overriding the default weekly schedule.\n\nConditional constraint (enforced server-side, not by the generated client):\n- Exactly one of `isClosed` (set to `true`) or `schedule` MUST be present.\n  Sending both, neither, or `isClosed: false` is a contract violation.\n",
      "required": [
       "startDate",
       "endDate"
      ],
      "properties": {
       "startDate": {
        "type": "string",
        "format": "date",
        "example": "2026-12-25"
       },
       "endDate": {
        "type": "string",
        "format": "date",
        "example": "2026-12-25"
       },
       "isClosed": {
        "type": "boolean",
        "description": "Marker flag indicating the locker is fully inaccessible for this range.\nWhen present it MUST be `true`; otherwise omit the field entirely.\nMutually exclusive with `schedule`.\n"
       },
       "schedule": {
        "type": "array",
        "minItems": 1,
        "description": "Overrides for specific weekdays within the exception range.\nMutually exclusive with `isClosed` — omit this field when `isClosed` is set.\n",
        "items": {
         "$ref": "#/components/schemas/weekly_period"
        },
        "example": [
         {
          "weekday": "MONDAY",
          "periods": [
           {
            "open": "10:00",
            "close": "16:00"
           }
          ]
         }
        ]
       }
      }
     }
    }
   },
   "metadata": {
    "type": "object",
    "description": "Metadata associated with the locker.",
    "properties": {
     "key": {
      "type": [
       "string",
       "null"
      ],
      "description": "The key of the metadata.",
      "example": "maxWeightCapacity"
     },
     "value": {
      "type": [
       "string",
       "null"
      ],
      "description": "The value of the metadata.",
      "example": "50kg"
     }
    }
   },
   "compartment": {
    "type": "object",
    "description": "Details about the compartments available in the locker.",
    "properties": {
     "size": {
      "description": "The size of the compartment. It is null when the stored size is not one of the known sizes.",
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "XXSMALL",
       "XSMALL",
       "SMALL",
       "XMEDIUM",
       "MEDIUM",
       "LARGE",
       "XLARGE",
       "XXLARGE",
       "ULARGE",
       "UULARGE",
       null
      ],
      "example": "MEDIUM"
     },
     "count": {
      "type": "integer",
      "description": "The number of compartments of this size available in the locker.",
      "example": 4
     },
     "height": {
      "type": "integer",
      "description": "The height of the compartment in millimeters.",
      "example": 400
     },
     "width": {
      "type": "integer",
      "description": "The width of the compartment in millimeters.",
      "example": 400
     },
     "length": {
      "type": "integer",
      "description": "The length of the compartment in millimeters.",
      "example": 600
     }
    }
   },
   "locker_response": {
    "type": "object",
    "properties": {
     "uid": {
      "type": "string",
      "description": "The internal unique identifier assigned to the locker.",
      "example": "1002377838"
     },
     "carrier": {
      "type": "object",
      "description": "The details of the locker on the Carrier's system.",
      "properties": {
       "lockerName": {
        "type": "string",
        "description": "The name assigned to the locker on the Carrier's system.",
        "example": "Berlin Locker 01"
       },
       "lockerId": {
        "type": [
         "string",
         "null"
        ],
        "description": "The identifier of the locker on the Carrier's system. `null` when the carrier has not set one.",
        "example": "XR1003"
       },
       "activationDate": {
        "type": [
         "string",
         "null"
        ],
        "format": "date-time",
        "description": "The date when the locker is to be activated for the carrier. `null` when not set.",
        "example": "2025-08-20T00:00:00Z"
       },
       "status": {
        "$ref": "#/components/schemas/status"
       }
      },
      "required": [
       "lockerName",
       "lockerId"
      ]
     },
     "provider": {
      "type": "object",
      "description": "The details of the locker on the Provider's system.",
      "properties": {
       "name": {
        "type": "string",
        "description": "The name of the locker provider.",
        "example": "KEBA"
       },
       "lockerModel": {
        "type": [
         "string",
         "null"
        ],
        "description": "The model of the locker provided by the provider. `null` when the provider has not sent one.",
        "example": "Model 1"
       },
       "lockerVersion": {
        "type": [
         "string",
         "null"
        ],
        "description": "The version of the locker model provided by the provider. `null` when the provider has not sent one.",
        "example": "v2.1"
       },
       "lockerName": {
        "type": "string",
        "description": "The name of the locker on the Provider's system.",
        "example": "BLOQ-Berlin-12045-001"
       },
       "lockerUid": {
        "type": "string",
        "description": "The unique identifier of the locker on the Provider's system.",
        "example": "PROVIDER_LOCKER_ABC123"
       },
       "status": {
        "type": "string",
        "description": "The status of the locker returned by the provider.",
        "enum": [
         "ACTIVE",
         "INACTIVE",
         "PLANNED"
        ],
        "example": "ACTIVE"
       }
      },
      "required": [
       "name",
       "lockerModel",
       "lockerVersion",
       "status"
      ]
     },
     "location": {
      "$ref": "#/components/schemas/location"
     },
     "features": {
      "description": "Features available in the locker. `null` when the locker has no feature data.",
      "oneOf": [
       {
        "$ref": "#/components/schemas/features"
       },
       {
        "type": "null"
       }
      ]
     },
     "openingHours": {
      "$ref": "#/components/schemas/opening_hours"
     },
     "metadata": {
      "type": [
       "array",
       "null"
      ],
      "description": "Additional metadata associated with the locker. `null` when the carrier locker has none.",
      "items": {
       "$ref": "#/components/schemas/metadata"
      }
     },
     "ownedByCarrier": {
      "type": [
       "string",
       "null"
      ],
      "description": "Indicates which carrier owns the locker. `null` means the locker belongs to a 3rd party provider.",
      "example": "GLS"
     },
     "compartmentTypes": {
      "type": [
       "array",
       "null"
      ],
      "description": "A list of different compartment types available in the locker.",
      "items": {
       "$ref": "#/components/schemas/compartment"
      },
      "example": [
       {
        "size": "SMALL",
        "count": 10,
        "height": 200,
        "width": 400,
        "length": 600
       },
       {
        "size": "MEDIUM",
        "count": 4,
        "height": 400,
        "width": 400,
        "length": 600
       },
       {
        "size": "LARGE",
        "count": 2,
        "height": 800,
        "width": 400,
        "length": 600
       }
      ]
     }
    },
    "required": [
     "uid",
     "carrier",
     "provider",
     "location"
    ]
   },
   "gateway_error": {
    "type": "object",
    "properties": {
     "message": {
      "type": "string",
      "description": "A message describing the error.",
      "example": "Unauthorized"
     },
     "request_id": {
      "type": "string",
      "description": "The identifier of the request at the API gateway. Include it when you report a problem.",
      "example": "a1eff468e84bcd6bbe3620047a6d5967"
     }
    },
    "required": [
     "message"
    ]
   },
   "carrier": {
    "type": "object",
    "description": "The details of the locker on the Carrier's system.",
    "properties": {
     "lockerName": {
      "type": "string",
      "description": "The name assigned to the locker on the Carrier's system.",
      "example": "Berlin Locker 01"
     },
     "lockerId": {
      "type": "string",
      "description": "The identifier of the locker on the Carrier's system.",
      "example": "XR1003"
     },
     "activationDate": {
      "type": "string",
      "format": "date-time",
      "description": "The date when the locker is to be activated for the carrier.",
      "example": "2025-08-20T00:00:00Z"
     }
    },
    "required": [
     "lockerName",
     "lockerId"
    ]
   },
   "carrier_input": {
    "description": "The carrier's details for the locker. Requests use these fields in addition to the shared carrier fields.",
    "allOf": [
     {
      "$ref": "#/components/schemas/carrier"
     },
     {
      "type": "object",
      "properties": {
       "mdmLockerId": {
        "type": "string",
        "description": "The identifier of the locker in the carrier's master data management system.",
        "example": "MDM-12345"
       },
       "dropoffBarcodeId": {
        "type": "string",
        "description": "The barcode identifier a courier scans to drop off parcels at this locker.",
        "example": "DROP-0001"
       },
       "checkoutLockerId": {
        "type": "string",
        "description": "The identifier of the locker in the carrier's checkout system.",
        "example": "CHK-0001"
       }
      }
     }
    ]
   },
   "provider": {
    "type": "object",
    "description": "The details of the locker on the Provider's system.",
    "properties": {
     "name": {
      "type": "string",
      "description": "The name of the locker provider.",
      "example": "KEBA"
     },
     "lockerModel": {
      "type": "string",
      "description": "The model of the locker provided by the provider.",
      "example": "Model 1"
     },
     "lockerVersion": {
      "type": "string",
      "description": "The version of the locker model provided by the provider.",
      "example": "v2.1"
     }
    },
    "required": [
     "name",
     "lockerModel",
     "lockerVersion"
    ]
   },
   "provider_input": {
    "description": "The provider's details for the locker. Requests use these fields in addition to the shared provider fields.",
    "allOf": [
     {
      "$ref": "#/components/schemas/provider"
     },
     {
      "type": "object",
      "properties": {
       "configurationName": {
        "type": "string",
        "description": "The name of the provider configuration to use for this locker.",
        "example": "default",
        "pattern": "^[A-Za-z0-9_.-]{1,64}$",
        "maxLength": 64
       }
      }
     }
    ]
   },
   "metadata_input": {
    "type": "object",
    "description": "A metadata entry to set on the locker. Both fields are required.",
    "required": [
     "key",
     "value"
    ],
    "properties": {
     "key": {
      "type": "string",
      "description": "The key of the metadata.",
      "example": "maxWeightCapacity"
     },
     "value": {
      "type": "string",
      "description": "The value of the metadata.",
      "example": "50kg"
     }
    }
   },
   "group": {
    "type": "object",
    "description": "Reference to a locker group to assign, identified by its type key and uid.",
    "properties": {
     "key": {
      "type": "string",
      "description": "The locker group type key. A locker may have at most one group per key.",
      "example": "DEPOT"
     },
     "uid": {
      "type": "string",
      "description": "The uid of the locker group.",
      "example": "6838265090"
     }
    },
    "required": [
     "key",
     "uid"
    ]
   },
   "create_input": {
    "type": "object",
    "properties": {
     "carrier": {
      "$ref": "#/components/schemas/carrier_input"
     },
     "provider": {
      "$ref": "#/components/schemas/provider_input"
     },
     "location": {
      "$ref": "#/components/schemas/location"
     },
     "metadata": {
      "type": "array",
      "description": "Additional metadata associated with the locker.",
      "items": {
       "$ref": "#/components/schemas/metadata_input"
      }
     },
     "features": {
      "$ref": "#/components/schemas/features"
     },
     "lockerGroups": {
      "type": "array",
      "description": "Locker groups to assign, identified by key and uid; at most one per type key.",
      "items": {
       "$ref": "#/components/schemas/group"
      }
     }
    },
    "required": [
     "carrier",
     "provider",
     "location"
    ]
   },
   "response_409": {
    "type": "object",
    "properties": {
     "errorCode": {
      "type": "string",
      "description": "A code representing the type of error.",
      "example": "CONFLICT"
     },
     "message": {
      "type": "string",
      "description": "A message describing the error.",
      "example": "The request conflicts with the current state of the resource"
     }
    }
   },
   "provider_update_input": {
    "type": "object",
    "description": "The provider fields a locker update can change.",
    "properties": {
     "configurationName": {
      "type": "string",
      "description": "The name of the provider configuration to use for this locker.",
      "example": "default",
      "pattern": "^[A-Za-z0-9_.-]{1,64}$",
      "maxLength": 64
     }
    }
   },
   "update_input": {
    "type": "object",
    "properties": {
     "carrier": {
      "$ref": "#/components/schemas/carrier_input"
     },
     "location": {
      "$ref": "#/components/schemas/location"
     },
     "metadata": {
      "type": "array",
      "description": "Additional metadata associated with the locker.",
      "items": {
       "$ref": "#/components/schemas/metadata_input"
      }
     },
     "features": {
      "$ref": "#/components/schemas/features"
     },
     "lockerGroups": {
      "type": "array",
      "description": "Locker groups to assign, identified by key and uid; at most one per type key. Omit to leave current groups unchanged.",
      "items": {
       "$ref": "#/components/schemas/group"
      }
     },
     "provider": {
      "$ref": "#/components/schemas/provider_update_input"
     }
    }
   },
   "update_status": {
    "type": "object",
    "properties": {
     "lockerUid": {
      "type": "string",
      "example": "678438790243767",
      "description": "The unique identifier of the locker in the GLS/NXT Platform"
     },
     "status": {
      "$ref": "#/components/schemas/status"
     }
    },
    "required": [
     "lockerUid",
     "status"
    ]
   },
   "locker_group_type": {
    "type": "object",
    "description": "A locker group type from the global catalog.",
    "properties": {
     "key": {
      "type": "string",
      "description": "The unique key identifying the locker group type.",
      "example": "DEPOT"
     },
     "category": {
      "type": "string",
      "description": "The category the locker group type belongs to.",
      "example": "DISTRIBUTION_CENTER"
     }
    },
    "required": [
     "key",
     "category"
    ]
   },
   "locker_group": {
    "type": "object",
    "description": "A locker group owned by the carrier.",
    "properties": {
     "uid": {
      "type": "string",
      "description": "The unique identifier of the locker group.",
      "example": "6838265090"
     },
     "key": {
      "type": "string",
      "description": "The locker group type key. A locker may belong to at most one group per key.",
      "example": "DEPOT"
     },
     "category": {
      "type": "string",
      "description": "The category the locker group type belongs to.",
      "example": "DISTRIBUTION_CENTER"
     },
     "name": {
      "type": "string",
      "description": "The name of the locker group.",
      "example": "Berlin Central"
     }
    },
    "required": [
     "key",
     "category",
     "name"
    ]
   },
   "locker_group_create_request": {
    "type": "object",
    "description": "Request to create a locker group.",
    "properties": {
     "typeKey": {
      "type": "string",
      "description": "The locker group type key from the global catalog.",
      "example": "DEPOT"
     },
     "name": {
      "type": "string",
      "description": "The name of the locker group.",
      "example": "Berlin Central"
     }
    },
    "required": [
     "typeKey",
     "name"
    ]
   },
   "locker_group_update_request": {
    "type": "object",
    "description": "Request to update a locker group.",
    "properties": {
     "name": {
      "type": "string",
      "description": "The new name of the locker group.",
      "example": "Berlin North"
     }
    },
    "required": [
     "name"
    ]
   },
   "locker_group_add_request": {
    "type": "object",
    "description": "Request to assign lockers to a locker group.",
    "properties": {
     "lockerUids": {
      "type": "array",
      "description": "The UIDs of the lockers to assign to the group.",
      "items": {
       "type": "string"
      },
      "example": [
       "10000019",
       "10000020"
      ]
     }
    },
    "required": [
     "lockerUids"
    ]
   },
   "locker_group_add_response": {
    "type": "object",
    "description": "The lockers that were assigned to the locker group.",
    "properties": {
     "lockersAdded": {
      "type": "array",
      "description": "The UIDs of the lockers that were assigned to the group.",
      "items": {
       "type": "string"
      },
      "example": [
       "10000019",
       "10000020"
      ]
     }
    },
    "required": [
     "lockersAdded"
    ]
   },
   "locker_group_remove_request": {
    "type": "object",
    "description": "Request to remove lockers from a locker group.",
    "properties": {
     "lockerUids": {
      "type": "array",
      "description": "The UIDs of the lockers to remove from the group.",
      "items": {
       "type": "string"
      },
      "example": [
       "10000019"
      ]
     }
    },
    "required": [
     "lockerUids"
    ]
   },
   "locker_group_removed_response": {
    "type": "object",
    "description": "The lockers that were removed from the locker group.",
    "properties": {
     "lockersRemoved": {
      "type": "array",
      "description": "The UIDs of the lockers that were removed from the group.",
      "items": {
       "type": "string"
      },
      "example": [
       "10000019"
      ]
     }
    },
    "required": [
     "lockersRemoved"
    ]
   },
   "network": {
    "type": "object",
    "description": "A network connecting a locker owner carrier with a tenant carrier.",
    "properties": {
     "uid": {
      "type": "integer",
      "format": "int64",
      "description": "The unique identifier of the network.",
      "example": 8065713862
     },
     "ownedBy": {
      "type": "string",
      "description": "The carrier that owns the network.",
      "example": "GLS_NXT"
     },
     "tenant": {
      "type": "string",
      "description": "The carrier that is the tenant of the network.",
      "example": "GLS_DE"
     },
     "autoShare": {
      "type": "boolean",
      "description": "When true, new lockers owned by this carrier are automatically added to the network.",
      "example": false
     }
    },
    "required": [
     "uid",
     "ownedBy",
     "tenant",
     "autoShare"
    ]
   },
   "network_locker": {
    "type": "object",
    "description": "A locker within a network, including its status from the provider, carrier, and network perspectives.",
    "properties": {
     "lockerUid": {
      "type": "integer",
      "format": "int64",
      "description": "The unique identifier of the locker.",
      "example": 10000019
     },
     "providerName": {
      "type": "string",
      "description": "The name of the locker provider.",
      "example": "MYFLEXBOX_DE"
     },
     "lockerName": {
      "type": [
       "string",
       "null"
      ],
      "description": "The carrier-assigned name for the locker.",
      "example": "Berlin Hauptbahnhof"
     },
     "providerLockerStatus": {
      "type": "string",
      "description": "The current status of the locker on the provider's side.",
      "example": "ACTIVE"
     },
     "carrierLockerStatus": {
      "type": [
       "string",
       "null"
      ],
      "description": "The status of the locker for the carrier.",
      "example": "ACTIVE"
     },
     "networkLockerStatus": {
      "type": [
       "string",
       "null"
      ],
      "description": "The status of the locker within the network.",
      "example": "PENDING"
     },
     "carrierLockerId": {
      "type": [
       "string",
       "null"
      ],
      "description": "The carrier-specific locker identifier.",
      "example": "3001"
     },
     "providerLockerId": {
      "type": [
       "string",
       "null"
      ],
      "description": "The provider-specific locker identifier.",
      "example": "68958"
     }
    },
    "required": [
     "lockerUid",
     "providerName",
     "providerLockerStatus"
    ]
   },
   "network_locker_page": {
    "type": "object",
    "description": "A paginated list of network lockers.",
    "properties": {
     "content": {
      "type": "array",
      "description": "The list of network lockers for the current page.",
      "items": {
       "$ref": "#/components/schemas/network_locker"
      }
     },
     "pageNumber": {
      "type": "integer",
      "format": "int32",
      "description": "The current page number (1-based).",
      "example": 1
     },
     "pageSize": {
      "type": "integer",
      "format": "int32",
      "description": "The number of items per page.",
      "example": 100
     },
     "totalElements": {
      "type": "integer",
      "format": "int64",
      "description": "The total number of lockers across all pages.",
      "example": 3
     },
     "isLast": {
      "type": "boolean",
      "description": "Whether this is the last page.",
      "example": true
     }
    },
    "required": [
     "content",
     "pageNumber",
     "pageSize",
     "totalElements",
     "isLast"
    ]
   },
   "network_locker_add_request": {
    "type": "object",
    "description": "Request to add lockers to a network.",
    "properties": {
     "lockerUids": {
      "type": "array",
      "description": "The list of locker UIDs to add to the network.",
      "items": {
       "type": "integer",
       "format": "int64"
      },
      "example": [
       10000019,
       10000020,
       10000021
      ]
     }
    },
    "required": [
     "lockerUids"
    ]
   },
   "network_locker_remove_request": {
    "type": "object",
    "description": "Request to remove lockers from a network.",
    "properties": {
     "lockerUids": {
      "type": "array",
      "description": "The list of locker UIDs to remove from the network.",
      "items": {
       "type": "integer",
       "format": "int64"
      },
      "example": [
       10000019,
       10000020
      ]
     }
    },
    "required": [
     "lockerUids"
    ]
   },
   "carrier_update": {
    "type": "object",
    "description": "Optional carrier details to update for a network locker.",
    "properties": {
     "lockerName": {
      "type": "string",
      "description": "The name assigned to the locker on the Carrier's system.",
      "example": "Berlin Locker 01"
     },
     "lockerId": {
      "type": "string",
      "description": "The identifier of the locker on the Carrier's system.",
      "example": "XR1003"
     },
     "activationDate": {
      "type": "string",
      "description": "The date when the locker is to be activated for the carrier.",
      "example": "2025-08-20T00:00:00Z"
     }
    }
   },
   "network_locker_patch": {
    "type": "object",
    "description": "Request to update the status of a locker within a network, optionally including carrier details.",
    "properties": {
     "networkLockerStatus": {
      "type": "string",
      "description": "The new status for the network locker.",
      "example": "ACCEPTED"
     },
     "carrier": {
      "$ref": "#/components/schemas/carrier_update"
     }
    },
    "required": [
     "networkLockerStatus"
    ]
   },
   "booking_type": {
    "type": "string",
    "description": "The type of booking request.",
    "enum": [
     "PRE_CHECK",
     "BOOKING"
    ],
    "example": "BOOKING"
   },
   "shipment_type_input": {
    "type": "string",
    "description": "The possible types of last-mile shipments accepted. Defaults to `LAST_MILE` when not present.",
    "enum": [
     "LAST_MILE",
     "ALTERNATIVE_DELIVERY"
    ],
    "example": "LAST_MILE"
   },
   "consignee": {
    "type": [
     "object",
     "null"
    ],
    "description": "The details of the consignee.",
    "properties": {
     "name": {
      "type": [
       "string",
       "null"
      ],
      "example": "John Doe"
     },
     "email": {
      "type": [
       "string",
       "null"
      ],
      "format": "email",
      "example": "john.doe@google.com"
     }
    }
   },
   "dimensions": {
    "type": "object",
    "additionalProperties": false,
    "description": "The dimensions of the parcel. A missing field counts as unknown, and the platform uses 10 mm for it.",
    "properties": {
     "depth": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "Depth in mm",
      "example": 190
     },
     "height": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "Height in mm",
      "example": 100
     },
     "width": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "Width in mm",
      "example": 140
     }
    }
   },
   "allocation_type": {
    "type": "string",
    "description": "The allocation type of the shipment.",
    "enum": [
     "HARD_RESERVATION",
     "SOFT_RESERVATION"
    ],
    "example": "HARD_RESERVATION"
   },
   "input_data": {
    "type": "object",
    "additionalProperties": false,
    "description": "If you send `consignee`, send both `name` and `email` as strings, and no other fields. The platform rejects a consignee with a missing, null or unknown field.",
    "properties": {
     "eventType": {
      "$ref": "#/components/schemas/booking_type"
     },
     "lockerUid": {
      "type": "string",
      "description": "The unique identifier of the locker in the GLS/NXT Platform.",
      "example": "locker_567890"
     },
     "carrierParcelId": {
      "type": "string",
      "description": "The identifier of the parcel in the carrier's system.",
      "example": "A123456789"
     },
     "shipmentType": {
      "$ref": "#/components/schemas/shipment_type_input"
     },
     "consignee": {
      "$ref": "#/components/schemas/consignee"
     },
     "dimensions": {
      "$ref": "#/components/schemas/dimensions"
     },
     "weight": {
      "type": "integer",
      "description": "Weight in grams",
      "example": 400
     },
     "allocationType": {
      "$ref": "#/components/schemas/allocation_type"
     },
     "requiresAccessibleCompartment": {
      "type": "boolean",
      "description": "Indicates whether the parcel requires an accessible compartment. Defaults to false when not present or null.",
      "default": false,
      "example": false
     },
     "secondaryShipmentId": {
      "type": "string",
      "description": "A secondary identifier for the shipment, separate from carrierParcelId.",
      "example": "EXP-CODE-0001"
     },
     "codAmount": {
      "type": "integer",
      "format": "int64",
      "description": "Cash-on-delivery amount to collect, expressed in minor units (e.g. cents).",
      "example": 2450
     },
     "codCurrency": {
      "type": "string",
      "description": "ISO 4217 currency code for `codAmount`.",
      "example": "EUR"
     },
     "lockStatus": {
      "type": "string",
      "enum": [
       "LOCKED",
       "UNLOCKED"
      ],
      "description": "The lock state to apply to the parcel on booking. `LOCKED` blocks the consignee from collecting the parcel; `UNLOCKED` releases it for collection.",
      "example": "LOCKED"
     }
    },
    "required": [
     "eventType",
     "carrierParcelId",
     "lockerUid",
     "dimensions"
    ]
   },
   "input_data_response": {
    "type": "object",
    "properties": {
     "status": {
      "type": "string",
      "description": "The status of the event processing.",
      "example": "success"
     },
     "message": {
      "type": "string",
      "description": "A message providing additional information about the event processing.",
      "example": "Parcel event received and processed successfully."
     },
     "timestamp": {
      "type": "string",
      "format": "date-time",
      "description": "The timestamp when the event was processed.",
      "example": "2023-06-18T10:45:00Z"
     }
    },
    "required": [
     "status",
     "message",
     "timestamp"
    ]
   },
   "parcel_input_error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "description": "A message describing the error.",
      "example": "Failed to parse request"
     }
    },
    "required": [
     "error"
    ]
   },
   "input_data_carrier_specific": {
    "type": "object",
    "additionalProperties": false,
    "description": "If you send `consignee`, send both `name` and `email` as strings, and no other fields. The platform rejects a consignee with a missing, null or unknown field.",
    "properties": {
     "eventType": {
      "$ref": "#/components/schemas/booking_type"
     },
     "carrierLockerId": {
      "type": "string",
      "description": "The unique identifier of the locker in the Carrier Platform.",
      "example": "LOCKER123"
     },
     "carrierParcelId": {
      "type": "string",
      "description": "The identifier of the parcel in the carrier's system.",
      "example": "12345KL6789M"
     },
     "shipmentType": {
      "$ref": "#/components/schemas/shipment_type_input"
     },
     "consignee": {
      "$ref": "#/components/schemas/consignee"
     },
     "dimensions": {
      "$ref": "#/components/schemas/dimensions"
     },
     "weight": {
      "type": "integer",
      "description": "Weight in grams",
      "example": 300
     },
     "allocationType": {
      "$ref": "#/components/schemas/allocation_type"
     },
     "requiresAccessibleCompartment": {
      "type": "boolean",
      "description": "Indicates whether the parcel requires an accessible compartment. Defaults to false when not present or null.",
      "default": false,
      "example": false
     },
     "secondaryShipmentId": {
      "type": "string",
      "description": "A secondary identifier for the shipment, separate from carrierParcelId.",
      "example": "EXP-CODE-0001"
     },
     "codAmount": {
      "type": "integer",
      "format": "int64",
      "description": "Cash-on-delivery amount to collect, expressed in minor units (e.g. cents).",
      "example": 2450
     },
     "codCurrency": {
      "type": "string",
      "description": "ISO 4217 currency code for `codAmount`.",
      "example": "EUR"
     },
     "lockStatus": {
      "type": "string",
      "enum": [
       "LOCKED",
       "UNLOCKED"
      ],
      "description": "The lock state to apply to the parcel on booking. `LOCKED` blocks the consignee from collecting the parcel; `UNLOCKED` releases it for collection.",
      "example": "LOCKED"
     }
    },
    "required": [
     "eventType",
     "carrierParcelId",
     "carrierLockerId",
     "dimensions"
    ]
   },
   "shipment_type": {
    "type": "string",
    "description": "The type of shipment.",
    "enum": [
     "LAST_MILE",
     "ALTERNATIVE_DELIVERY",
     "FIRST_MILE",
     "RETURN"
    ],
    "example": "LAST_MILE"
   },
   "dimensions_status": {
    "type": "string",
    "description": "The status of the parcel dimensions. The parcel API sends `PARCEL_DIMENSIONS_EXCEEDED` for a parcel that is too big; webhooks send `PARCEL_DIMENSIONS_EXCEED`.",
    "enum": [
     "PARCEL_DIMENSIONS_EXCEED",
     "PARCEL_DIMENSIONS_EXCEEDED",
     "PARCEL_DIMENSIONS_OK",
     "PARCEL_DIMENSIONS_UNKNOWN"
    ],
    "example": "PARCEL_DIMENSIONS_OK"
   },
   "shipment_status": {
    "type": "string",
    "description": "The status of the shipment. `LOCKED`, `UNLOCKED` and `CONSIGNEE_PAID` are milestones in a parcel's `events`; they are never the parcel's `shipmentStatus`.",
    "enum": [
     "BOOKING_PRE_CHECK",
     "BOOKING_REQUESTED",
     "BOOKING_CREATED",
     "BOOKING_CANCELLED",
     "BOOKING_CANCELLATION_FAILED",
     "BOOKING_EXPIRED",
     "BOOKING_REJECTED_INVALID_LOCKER",
     "BOOKING_REJECTED_PROVIDER_ERROR",
     "BOOKING_REJECTED_LOCKER_IS_FULL",
     "BOOKING_REJECTED_NO_FREE_FITTING_COMPARTMENT",
     "BOOKING_REJECTED_LOCKER_UNAVAILABLE",
     "BOOKING_REJECTED_DIMENSIONS_EXCEED",
     "BOOKING_REJECTED_INVALID_CONSIGNEE",
     "BOOKING_REJECTED_NO_ACCESSIBLE_COMPARTMENT",
     "COURIER_DELIVERED",
     "COURIER_DELIVERY_EXPIRED",
     "COURIER_DELIVERY_LABEL_SCANNED",
     "COURIER_DELIVERY_ERROR",
     "COURIER_COLLECTED",
     "COURIER_COLLECTED_EXPIRED",
     "COURIER_COLLECTION_LABEL_SCANNED",
     "COURIER_COLLECTION_LABEL_NOT_AVAILABLE",
     "CONSIGNEE_COLLECTED",
     "CONSIGNEE_PAID",
     "CONSIGNEE_DELIVERED",
     "CONSIGNEE_DELIVERY_EXPIRED",
     "CONSIGNEE_COLLECTION_EXPIRED",
     "PARCEL_TO_BE_EXPIRED",
     "DELIVERY_PARCEL_TOO_BIG",
     "DELIVERY_COMPARTMENT_BROKEN",
     "DELIVERY_COMPARTMENT_OCCUPIED",
     "DELIVERY_NOT_POSSIBLE",
     "COLLECTION_PARCEL_NOT_AVAILABLE",
     "COLLECTION_COMPARTMENT_BROKEN",
     "COLLECTION_NOT_POSSIBLE",
     "MAINTENANCE_COLLECTED",
     "LOCKED",
     "UNLOCKED"
    ],
    "example": "CONSIGNEE_COLLECTED"
   },
   "code": {
    "type": [
     "object",
     "null"
    ],
    "description": "Access codes with valid until timestamp.",
    "properties": {
     "code": {
      "type": "string",
      "example": "anyValidCode123"
     },
     "validUntil": {
      "type": "string",
      "format": "date-time",
      "example": "2025-01-27T12:00:00Z",
      "description": "Code validity in UTC timestamp [ISO 8601](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) format."
     }
    },
    "required": [
     "code"
    ]
   },
   "access_codes": {
    "type": [
     "object",
     "null"
    ],
    "description": "Access codes for the parcel",
    "properties": {
     "consigneeCollection": {
      "type": "string",
      "example": "anyValidCode123",
      "deprecated": true
     },
     "consigneeCollectionCode": {
      "type": "object",
      "$ref": "#/components/schemas/code",
      "description": "The access code for the consignee collection"
     }
    }
   },
   "parcel_events": {
    "type": "array",
    "items": {
     "type": "object",
     "properties": {
      "timestamp": {
       "type": "string",
       "format": "date-time",
       "example": "2025-08-20T00:00:00Z"
      },
      "eventType": {
       "$ref": "#/components/schemas/shipment_status"
      }
     }
    }
   },
   "signature": {
    "type": [
     "object",
     "null"
    ],
    "description": "A Base64-encoded image representing the consignee's signature, captured upon parcel collection",
    "properties": {
     "imageBase64": {
      "type": "string",
      "example": "imageBase64StringHere"
     },
     "format": {
      "type": "string",
      "example": ""
     }
    }
   },
   "parcel_response": {
    "type": "object",
    "properties": {
     "shipmentUid": {
      "type": "string",
      "example": "anyParcelId123",
      "description": "The unique identifier of the parcel shipment in the GLS/NXT Platform"
     },
     "lockerUid": {
      "type": "string",
      "example": "anyLockerId123",
      "description": "The unique identifier of the locker in the GLS/NXT Platform"
     },
     "carrierParcelId": {
      "type": "string",
      "example": "anyCarrierParcelId123",
      "description": "The identifier of the parcel in the carrier's system"
     },
     "carrierLockerId": {
      "type": [
       "string",
       "null"
      ],
      "example": "Locker1",
      "description": "The identifier of the locker in the carrier's system"
     },
     "shipmentType": {
      "description": "The type of shipment. `null` when the platform received no shipment type for the parcel.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/shipment_type"
       },
       {
        "type": "null"
       }
      ]
     },
     "dimensionsStatus": {
      "$ref": "#/components/schemas/dimensions_status"
     },
     "shipmentStatus": {
      "$ref": "#/components/schemas/shipment_status"
     },
     "isFinal": {
      "type": "boolean",
      "example": true
     },
     "accessCodes": {
      "$ref": "#/components/schemas/access_codes"
     },
     "consignee": {
      "$ref": "#/components/schemas/consignee"
     },
     "events": {
      "$ref": "#/components/schemas/parcel_events"
     },
     "allocationType": {
      "description": "The allocation type of the shipment. `null` when the platform received no allocation type for the parcel.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/allocation_type"
       },
       {
        "type": "null"
       }
      ]
     },
     "providerName": {
      "type": [
       "string",
       "null"
      ],
      "example": "LOCKY_PT",
      "description": "The name of the locker network provider"
     },
     "providerLockerId": {
      "type": [
       "string",
       "null"
      ],
      "example": "1178",
      "description": "The identifier of the locker in the provider's system"
     },
     "shipmentSignature": {
      "$ref": "#/components/schemas/signature"
     },
     "requiresAccessibleCompartment": {
      "type": "boolean",
      "example": true
     },
     "labelType": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "LABELLESS",
       "LABELED",
       null
      ],
      "example": "LABELLESS",
      "description": "Label mode for the shipment. `LABELLESS` means no printed label is used and `LABELED` means a printed label is used."
     },
     "referenceCode": {
      "type": [
       "string",
       "null"
      ],
      "example": "LBL000000018",
      "description": "Reference code scanned by driver during pickup of the labelless parcel. This field is only relevant for `LABELLESS` shipments."
     },
     "secondaryShipmentId": {
      "type": [
       "string",
       "null"
      ],
      "example": "EXP-CODE-0001",
      "description": "A secondary identifier for the shipment, separate from `carrierParcelId`."
     },
     "paymentStatus": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "EXPECTED",
       "PAID",
       "FAILED",
       null
      ],
      "example": "PAID",
      "description": "The current cash-on-delivery payment status for the shipment, when applicable. Absent when the shipment carries no CoD payment."
     },
     "codAmount": {
      "type": [
       "integer",
       "null"
      ],
      "format": "int64",
      "example": 2450,
      "description": "Cash-on-delivery amount to collect, expressed in minor units (e.g. cents). Absent when the shipment carries no CoD payment."
     },
     "codCurrency": {
      "type": [
       "string",
       "null"
      ],
      "example": "EUR",
      "description": "ISO 4217 currency code for `codAmount`. Absent when the shipment carries no CoD payment."
     },
     "paymentType": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "CARD",
       "FLIK",
       null
      ],
      "example": "CARD",
      "description": "The payment method used for a cash-on-delivery parcel, as reported by the locker provider. Absent when the shipment carries no CoD payment."
     },
     "lockStatus": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "LOCKED",
       "UNLOCKED",
       null
      ],
      "example": "LOCKED",
      "description": "The current provider lock state of the parcel, when known. `LOCKED` means the consignee cannot collect the parcel (e.g. a cash-on-delivery payment is still pending); `UNLOCKED` means it can be collected. Absent when the parcel carries no lock state."
     },
     "signature": {
      "$ref": "#/components/schemas/signature",
      "deprecated": true,
      "description": "The same value as `shipmentSignature`. Sent only when the parcel has a signature. Use `shipmentSignature` instead."
     }
    },
    "required": [
     "shipmentUid",
     "lockerUid",
     "carrierParcelId",
     "dimensionsStatus",
     "shipmentStatus",
     "isFinal",
     "consignee",
     "requiresAccessibleCompartment"
    ]
   },
   "sma_error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "description": "A message describing the error.",
      "example": "Malformed request body"
     }
    },
    "required": [
     "error"
    ]
   },
   "parcel_page": {
    "type": "object",
    "description": "A paginated list of parcels.",
    "properties": {
     "content": {
      "type": "array",
      "description": "The list of parcels for the current page.",
      "items": {
       "$ref": "#/components/schemas/parcel_response"
      }
     },
     "pageNumber": {
      "type": "integer",
      "format": "int32",
      "description": "The current page number (1-based).",
      "example": 1
     },
     "pageSize": {
      "type": "integer",
      "format": "int32",
      "description": "The number of items per page.",
      "example": 30
     },
     "isLast": {
      "type": "boolean",
      "description": "Whether this is the last page.",
      "example": true
     }
    },
    "required": [
     "content",
     "pageNumber",
     "pageSize",
     "isLast"
    ]
   },
   "parcel_lock_request": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "status"
    ],
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "LOCKED",
       "UNLOCKED"
      ],
      "example": "LOCKED",
      "description": "The lock state to apply. `LOCKED` blocks the consignee from collecting the parcel; `UNLOCKED` releases it for collection."
     },
     "reason": {
      "type": "string",
      "enum": [
       "CASH_ON_DELIVERY",
       "POLICE_HOLD",
       "OTHER"
      ],
      "example": "CASH_ON_DELIVERY",
      "description": "Why the parcel is being locked. Optional. On `LOCKED` it defaults to `CASH_ON_DELIVERY` when omitted. On `UNLOCKED` it is ignored — the parcel's original lock reason determines how it is released."
     }
    }
   },
   "MockServiceError": {
    "type": "object",
    "x-internal": true,
    "required": [
     "message"
    ],
    "properties": {
     "message": {
      "type": "string",
      "description": "Error message.",
      "example": "Missing provider_name parameter in request body"
     }
    }
   },
   "mock_parcel_event": {
    "type": "object",
    "x-internal": true,
    "description": "A Parcel Updates webhook body, unchanged. The fields below are the ones that the platform sends; see the Parcel Updates webhook for their meaning. This schema is documentation only. The mock does not check the stored body against it, and the tests check it only against sample bodies. The Parcel Updates webhook in the carrier-gateway specification is the contract.",
    "required": [
     "carrierParcelId"
    ],
    "properties": {
     "shipmentUid": {
      "type": "string",
      "example": "7c1f0f0e-9b1e-4f43-9d55-0d9f0c1a2b3c"
     },
     "lockerUid": {
      "type": "string",
      "example": "1002377838"
     },
     "carrierParcelId": {
      "type": "string",
      "example": "000123456789"
     },
     "carrierLockerId": {
      "type": [
       "string",
       "null"
      ],
      "example": "99663306"
     },
     "compartmentId": {
      "type": [
       "string",
       "null"
      ],
      "example": "A-01"
     },
     "compartmentSize": {
      "type": [
       "string",
       "null"
      ],
      "example": "MEDIUM"
     },
     "mdmLocationId": {
      "type": [
       "string",
       "null"
      ],
      "example": "123456"
     },
     "barcodeContent": {
      "type": [
       "string",
       "null"
      ],
      "example": "LBL000000018"
     },
     "shipmentType": {
      "type": "string",
      "example": "LAST_MILE"
     },
     "dimensionsStatus": {
      "type": "string",
      "example": "PARCEL_DIMENSIONS_OK"
     },
     "shipmentStatus": {
      "type": [
       "string",
       "null"
      ],
      "example": "COURIER_DELIVERED"
     },
     "isFinal": {
      "type": [
       "boolean",
       "null"
      ],
      "example": false
     },
     "accessCodes": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "consigneeCollection": {
        "type": [
         "string",
         "null"
        ],
        "example": "342156"
       },
       "consigneeCollectionCode": {
        "type": [
         "object",
         "null"
        ],
        "properties": {
         "code": {
          "type": [
           "string",
           "null"
          ],
          "example": "342156"
         },
         "validUntil": {
          "type": [
           "string",
           "null"
          ],
          "format": "date-time",
          "example": "2026-08-20T00:00:00Z"
         }
        },
        "x-internal": true
       }
      },
      "x-internal": true
     },
     "consignee": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "name": {
        "type": [
         "string",
         "null"
        ]
       },
       "email": {
        "type": [
         "string",
         "null"
        ]
       }
      },
      "x-internal": true
     },
     "events": {
      "type": [
       "array",
       "null"
      ],
      "items": {
       "type": "object",
       "properties": {
        "eventType": {
         "type": "string",
         "example": "COURIER_DELIVERED"
        },
        "timestamp": {
         "type": [
          "string",
          "null"
         ],
         "format": "date-time",
         "example": "2026-08-20T00:00:00Z"
        }
       },
       "x-internal": true
      },
      "x-internal": true
     },
     "allocationType": {
      "type": [
       "string",
       "null"
      ],
      "example": "HARD_RESERVATION"
     },
     "carrierName": {
      "type": [
       "string",
       "null"
      ],
      "example": "GLS_NXT"
     },
     "providerName": {
      "type": [
       "string",
       "null"
      ],
      "example": "KEBA"
     },
     "providerLockerId": {
      "type": [
       "string",
       "null"
      ],
      "example": "99663306"
     },
     "shipmentSignature": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "imageBase64": {
        "type": [
         "string",
         "null"
        ]
       },
       "format": {
        "type": [
         "string",
         "null"
        ]
       }
      },
      "x-internal": true
     },
     "requiresAccessibleCompartment": {
      "type": [
       "boolean",
       "null"
      ],
      "example": false
     },
     "labelType": {
      "type": [
       "string",
       "null"
      ],
      "example": "LABELED"
     },
     "referenceCode": {
      "type": [
       "string",
       "null"
      ],
      "example": "LBL-000123456789"
     },
     "secondaryShipmentId": {
      "type": [
       "string",
       "null"
      ],
      "example": "EXP-CODE-0001"
     },
     "eventTimestamp": {
      "type": [
       "string",
       "null"
      ],
      "format": "date-time",
      "example": "2026-08-20T00:00:00Z"
     }
    }
   },
   "mock_locker_event": {
    "type": "object",
    "x-internal": true,
    "description": "A Locker Updates webhook body, unchanged. The fields below are the ones that the platform sends; see the Locker Updates webhook for their meaning. This schema is documentation only. The mock does not check the stored body against it, and the tests check it only against sample bodies. The Locker Updates webhook in the carrier-gateway specification is the contract.",
    "required": [
     "eventTimestamp",
     "uid"
    ],
    "properties": {
     "eventTimestamp": {
      "type": "string",
      "format": "date-time",
      "example": "2026-08-20T00:00:00Z"
     },
     "uid": {
      "type": "string",
      "example": "1002377838"
     },
     "carrier": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "lockerName": {
        "type": "string",
        "example": "Test Locker 01"
       },
       "lockerId": {
        "type": "string",
        "example": "99663306"
       },
       "activationDate": {
        "type": [
         "string",
         "null"
        ],
        "format": "date-time",
        "example": "2026-08-20T00:00:00Z"
       },
       "status": {
        "type": "string",
        "example": "ACTIVE"
       }
      },
      "x-internal": true
     },
     "provider": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "name": {
        "type": "string",
        "example": "KEBA"
       },
       "lockerModel": {
        "type": "string",
        "example": "Model 1"
       },
       "lockerVersion": {
        "type": "string",
        "example": "v2.1"
       },
       "lockerName": {
        "type": [
         "string",
         "null"
        ]
       },
       "lockerUid": {
        "type": [
         "string",
         "null"
        ],
        "example": "99663306"
       },
       "status": {
        "type": "string",
        "example": "ACTIVE"
       }
      },
      "x-internal": true
     },
     "location": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "street": {
        "type": "string"
       },
       "streetNumber": {
        "type": "string"
       },
       "postalCode": {
        "type": "string"
       },
       "city": {
        "type": "string"
       },
       "lon": {
        "type": "number",
        "format": "double"
       },
       "lat": {
        "type": "number",
        "format": "double"
       },
       "countryCode": {
        "type": "string",
        "example": "DE"
       },
       "type": {
        "type": [
         "string",
         "null"
        ],
        "example": "indoor"
       }
      },
      "x-internal": true
     },
     "features": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "hasScreen": {
        "type": [
         "boolean",
         "null"
        ]
       },
       "hasPinPad": {
        "type": [
         "boolean",
         "null"
        ]
       },
       "hasPinBarcodeReader": {
        "type": [
         "boolean",
         "null"
        ]
       }
      },
      "x-internal": true
     },
     "openingHours": {
      "type": [
       "object",
       "null"
      ],
      "description": "Same structure as `openingHours` in the Locker Updates webhook."
     },
     "metadata": {
      "type": [
       "array",
       "null"
      ],
      "items": {
       "type": "object",
       "properties": {
        "key": {
         "type": [
          "string",
          "null"
         ]
        },
        "value": {
         "type": [
          "string",
          "null"
         ]
        }
       },
       "x-internal": true
      },
      "x-internal": true
     },
     "ownedByCarrier": {
      "type": [
       "string",
       "null"
      ],
      "example": "GLS"
     },
     "compartmentTypes": {
      "type": [
       "array",
       "null"
      ],
      "items": {
       "type": "object",
       "properties": {
        "size": {
         "type": "string",
         "example": "MEDIUM"
        },
        "count": {
         "type": "integer",
         "example": 4
        },
        "width": {
         "type": "integer",
         "example": 400
        },
        "height": {
         "type": "integer",
         "example": 400
        },
        "length": {
         "type": "integer",
         "example": 600
        }
       },
       "x-internal": true
      },
      "x-internal": true
     }
    }
   },
   "mock_collection_event": {
    "type": "object",
    "x-internal": true,
    "description": "A Collection Notification webhook body, unchanged. The fields below are the ones that the platform sends; see the Collection Notification webhook for their meaning. This schema is documentation only. The mock does not check the stored body against it, and the tests check it only against sample bodies. The Collection Notification webhook in the carrier-gateway specification is the contract.",
    "required": [
     "lockerUid"
    ],
    "properties": {
     "eventTimestamp": {
      "type": "string",
      "format": "date-time",
      "example": "2026-08-20T00:00:00Z"
     },
     "lockerUid": {
      "type": "string",
      "example": "1002377838"
     },
     "carrierLockerId": {
      "type": [
       "string",
       "null"
      ],
      "example": "99663306"
     },
     "courierAccessCode": {
      "type": [
       "string",
       "null"
      ],
      "example": "342156"
     },
     "parcels": {
      "type": [
       "array",
       "null"
      ],
      "items": {
       "type": "object",
       "properties": {
        "carrierParcelId": {
         "type": "string",
         "example": "000123456789"
        }
       },
       "x-internal": true
      },
      "x-internal": true
     }
    }
   },
   "webhook_locker_carrier": {
    "allOf": [
     {
      "$ref": "#/components/schemas/carrier"
     },
     {
      "type": "object",
      "required": [
       "status"
      ],
      "properties": {
       "status": {
        "type": "string",
        "description": "The status of the locker for the carrier. carrier-gateway sends `INITIAL` and `PLANNED` as `INACTIVE`.\n",
        "enum": [
         "ACTIVE",
         "INACTIVE",
         "MAINTENANCE",
         "DECOMMISSIONED"
        ],
        "example": "ACTIVE"
       }
      }
     }
    ]
   },
   "webhook_locker_provider": {
    "allOf": [
     {
      "$ref": "#/components/schemas/provider"
     },
     {
      "type": "object",
      "required": [
       "lockerUid",
       "status"
      ],
      "properties": {
       "lockerName": {
        "type": "string",
        "description": "The name of the locker on the Provider's system.",
        "example": "BLOQ-Berlin-12045-001"
       },
       "lockerUid": {
        "type": "string",
        "description": "The unique identifier of the locker on the Provider's system.",
        "example": "PROVIDER_LOCKER_ABC123"
       },
       "status": {
        "type": "string",
        "description": "The status of the locker returned by the provider. carrier-gateway sends `PLANNED` as `INACTIVE`.",
        "enum": [
         "ACTIVE",
         "INACTIVE"
        ],
        "example": "ACTIVE"
       }
      }
     }
    ]
   },
   "webhook_location": {
    "type": "object",
    "description": "Details about the geographical location of the locker.",
    "required": [
     "street",
     "streetNumber",
     "postalCode",
     "city",
     "lon",
     "lat",
     "countryCode"
    ],
    "properties": {
     "street": {
      "type": "string",
      "description": "The street name where the locker is located.",
      "example": "Main Street"
     },
     "streetNumber": {
      "type": "string",
      "description": "The street number of the locker location. Empty when the locker has no street number.",
      "example": "1"
     },
     "postalCode": {
      "type": "string",
      "description": "The postal code of the locker location.",
      "example": "90210"
     },
     "city": {
      "type": "string",
      "description": "The city where the locker is located.",
      "example": "Berlin"
     },
     "lon": {
      "type": "number",
      "format": "double",
      "description": "The longitude coordinate of the locker location.",
      "example": -118.2437
     },
     "lat": {
      "type": "number",
      "format": "double",
      "description": "The latitude coordinate of the locker location.",
      "example": 34.0522
     },
     "countryCode": {
      "type": "string",
      "description": "The ISO 3166-1 alpha-2 country code for the locker location.",
      "example": "DE"
     },
     "locationType": {
      "type": "string",
      "description": "Whether the locker is indoors or outdoors, for example `indoor` or `outdoor`. Absent when unspecified.",
      "example": "indoor"
     },
     "locationSubtype": {
      "type": "string",
      "description": "The kind of place where the locker is, for example `GAS_STATION` or `RETAIL_SUPERMARKETS`. Absent when unspecified.",
      "example": "GAS_STATION"
     }
    }
   },
   "webhook_locker_owner": {
    "type": "object",
    "description": "The owner of the locker. Absent when the platform has no owner for the locker.",
    "required": [
     "name",
     "type"
    ],
    "properties": {
     "name": {
      "type": "string",
      "description": "The name of the owner, a carrier or a locker provider.",
      "example": "GLS"
     },
     "type": {
      "type": "string",
      "description": "Whether the owner is a carrier or a locker provider.",
      "enum": [
       "CARRIER",
       "PROVIDER"
      ],
      "example": "CARRIER"
     }
    }
   },
   "webhook_update_request": {
    "type": "object",
    "description": "The locker data that carrier-gateway sends when a locker of the carrier is created or changes.\ncarrier-gateway omits an optional field when it has no value; it never sends `null`.\n",
    "required": [
     "uid",
     "carrier",
     "provider",
     "location",
     "features",
     "metadata",
     "compartmentTypes",
     "eventTimestamp"
    ],
    "properties": {
     "uid": {
      "type": "string",
      "description": "The internal unique identifier assigned to the locker.",
      "example": "1002377838"
     },
     "carrier": {
      "$ref": "#/components/schemas/webhook_locker_carrier"
     },
     "provider": {
      "$ref": "#/components/schemas/webhook_locker_provider"
     },
     "location": {
      "$ref": "#/components/schemas/webhook_location"
     },
     "features": {
      "$ref": "#/components/schemas/features"
     },
     "metadata": {
      "type": "array",
      "description": "Additional metadata associated with the locker.",
      "items": {
       "$ref": "#/components/schemas/metadata"
      }
     },
     "compartmentTypes": {
      "type": "array",
      "description": "A list of different compartment types available in the locker.",
      "items": {
       "$ref": "#/components/schemas/compartment"
      }
     },
     "eventTimestamp": {
      "type": "string",
      "format": "date-time",
      "example": "2025-08-20T00:00:00Z",
      "description": "The timestamp of the locker status update."
     },
     "openingHours": {
      "$ref": "#/components/schemas/opening_hours"
     },
     "owner": {
      "$ref": "#/components/schemas/webhook_locker_owner"
     }
    }
   },
   "parcel_event": {
    "type": "object",
    "required": [
     "shipmentUid",
     "lockerUid",
     "carrierParcelId",
     "carrierLockerId",
     "carrierName",
     "shipmentType",
     "shipmentStatus",
     "dimensionsStatus",
     "events",
     "eventTimestamp"
    ],
    "properties": {
     "shipmentUid": {
      "type": "string",
      "example": "anyParcelId123",
      "description": "The unique identifier of the parcel shipment in the GLS/NXT Platform"
     },
     "lockerUid": {
      "type": "string",
      "example": "anyLockerId123",
      "description": "The unique identifier of the locker in the GLS/NXT Platform"
     },
     "carrierParcelId": {
      "type": "string",
      "example": "anyCarrierParcelId123",
      "description": "The identifier of the parcel in the carrier's system"
     },
     "carrierLockerId": {
      "type": "string",
      "example": "Locker1",
      "description": "The identifier of the locker in the carrier's system"
     },
     "compartmentId": {
      "type": [
       "string",
       "null"
      ],
      "example": "A-01",
      "description": "The identifier of the compartment assigned to the parcel"
     },
     "compartmentSize": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "XXSMALL",
       "XSMALL",
       "SMALL",
       "XMEDIUM",
       "MEDIUM",
       "LARGE",
       "XLARGE",
       "XXLARGE",
       "ULARGE",
       "UULARGE",
       null
      ],
      "example": "MEDIUM",
      "description": "The size of the compartment assigned to the parcel"
     },
     "mdmLocationId": {
      "type": [
       "string",
       "null"
      ],
      "example": "123456",
      "description": "Specific to certain carriers only. The MDM location identifier associated with the parcel locker"
     },
     "barcodeContent": {
      "type": [
       "string",
       "null"
      ],
      "example": "LBL000000018",
      "description": "Specific to certain carriers only. The barcode content associated with the parcel"
     },
     "shipmentType": {
      "$ref": "#/components/schemas/shipment_type"
     },
     "dimensionsStatus": {
      "$ref": "#/components/schemas/dimensions_status"
     },
     "shipmentStatus": {
      "$ref": "#/components/schemas/shipment_status"
     },
     "accessCodes": {
      "$ref": "#/components/schemas/access_codes"
     },
     "consignee": {
      "$ref": "#/components/schemas/consignee"
     },
     "events": {
      "$ref": "#/components/schemas/parcel_events"
     },
     "allocationType": {
      "$ref": "#/components/schemas/allocation_type"
     },
     "carrierName": {
      "type": "string",
      "example": "GLS_DE",
      "description": "The name of the carrier"
     },
     "providerName": {
      "type": [
       "string",
       "null"
      ],
      "example": "LOCKY_PT",
      "description": "The name of the locker network provider"
     },
     "providerLockerId": {
      "type": [
       "string",
       "null"
      ],
      "example": "1178",
      "description": "The identifier of the locker in the provider's system"
     },
     "signature": {
      "type": "string",
      "deprecated": true,
      "example": "imageBase64StringHere",
      "description": "The Base64-encoded signature image. Deprecated, use `shipmentSignature.imageBase64`. Absent when there is no signature."
     },
     "shipmentSignature": {
      "$ref": "#/components/schemas/signature"
     },
     "requireEasyAccess": {
      "type": "boolean",
      "example": true,
      "description": "Whether the parcel needs an accessible compartment. Absent when the platform did not say."
     },
     "labelType": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "LABELLESS",
       "LABELED",
       null
      ],
      "example": "LABELLESS",
      "description": "Label mode for the shipment. `LABELLESS` means no printed label is used and `LABELED` means a printed label is used."
     },
     "referenceCode": {
      "type": [
       "string",
       "null"
      ],
      "example": "LBL000000018",
      "description": "Reference code scanned by driver during pickup of the labelless parcel. This field is only relevant for `LABELLESS` shipments."
     },
     "secondaryShipmentId": {
      "type": [
       "string",
       "null"
      ],
      "example": "EXP-CODE-0001",
      "description": "A secondary identifier for the shipment, separate from `carrierParcelId`."
     },
     "lockStatus": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "LOCKED",
       "UNLOCKED",
       null
      ],
      "example": "LOCKED",
      "description": "The current provider lock state of the parcel, when known. `LOCKED` means the consignee cannot collect the parcel (e.g. a cash-on-delivery payment is still pending); `UNLOCKED` means it can be collected. Absent when the parcel carries no lock state."
     },
     "codAmount": {
      "type": [
       "integer",
       "null"
      ],
      "format": "int64",
      "example": 2450,
      "description": "The cash-on-delivery amount to collect from the consignee, in the currency's minor units (e.g. cents). Absent for parcels without cash-on-delivery."
     },
     "codCurrency": {
      "type": [
       "string",
       "null"
      ],
      "example": "EUR",
      "description": "ISO 4217 currency code for `codAmount`. Absent when `codAmount` is absent."
     },
     "paymentType": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "CARD",
       "FLIK",
       null
      ],
      "example": "CARD",
      "description": "The method the consignee paid a cash-on-delivery parcel with, as reported by the locker provider. The value set is country-specific: Slovenia (`GLS_SI`) is the only country live with cash-on-delivery today and reports `CARD` or `FLIK`, and the enum is extended as further countries are enabled. Absent for parcels without cash-on-delivery, before the payment is made, and when the provider reported no method or one outside the agreed set."
     },
     "eventTimestamp": {
      "type": "string",
      "format": "date-time",
      "example": "2025-08-20T00:00:00Z",
      "description": "The timestamp of the parcel update"
     }
    }
   },
   "collection_events": {
    "type": "object",
    "required": [
     "eventTimestamp",
     "lockerUid",
     "carrierLockerId",
     "parcels"
    ],
    "properties": {
     "eventTimestamp": {
      "type": "string",
      "format": "date-time",
      "example": "2025-08-20T00:00:00Z",
      "description": "The timestamp of the collection event"
     },
     "lockerUid": {
      "type": "string",
      "description": "The unique identifier of the locker in the GLS/NXT Platform",
      "example": "8979879823"
     },
     "carrierLockerId": {
      "type": "string",
      "description": "The unique identifier of the locker in the Carrier's system",
      "example": "GHX1234"
     },
     "courierAccessCode": {
      "type": [
       "string",
       "null"
      ],
      "description": "Access code for the courier to collect parcels from locker. Access code rotates daily.",
      "example": "342156"
     },
     "parcels": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "carrierParcelId"
       ],
       "properties": {
        "carrierParcelId": {
         "type": "string",
         "description": "The identifier of the parcel in the carrier's system",
         "example": "1234212321"
        }
       }
      }
     }
    }
   }
  },
  "responses": {
   "200": {
    "description": "Return a 200 status to indicate that the data was received successfully."
   },
   "401": {
    "description": "Return a 401 status to indicate that the POST was unauthorized."
   },
   "500": {
    "description": "Return a 500 status to indicate that the POST was unsuccessfully processed."
   },
   "response_400": {
    "description": "Bad request due to invalid input.",
    "content": {
     "application/json": {
      "schema": {
       "type": "object",
       "properties": {
        "errorCode": {
         "type": "string",
         "description": "A code representing the type of error.",
         "example": "Bad Request"
        },
        "message": {
         "type": "string",
         "description": "A message describing the error.",
         "example": "ids parameter is required"
        }
       },
       "required": [
        "errorCode",
        "message"
       ]
      }
     }
    }
   },
   "gateway_401": {
    "description": "The `X-API-Key` header is missing or not valid. The API gateway sends this response.",
    "x-ooh-gateway-response": true,
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/gateway_error"
      },
      "example": {
       "message": "No API key found in request",
       "request_id": "7ffd2e0e5888950b8932023263c33c26"
      }
     }
    }
   },
   "response_500": {
    "description": "The server encountered an internal error.",
    "content": {
     "application/json": {
      "schema": {
       "type": "object",
       "properties": {
        "errorCode": {
         "type": "string",
         "description": "A code representing the type of error.",
         "example": "Internal Server Error"
        },
        "message": {
         "type": "string",
         "description": "A message describing the error.",
         "example": "The server encountered an internal error"
        }
       }
      }
     }
    }
   },
   "response_404": {
    "description": "The requested resource was not found.",
    "content": {
     "application/json": {
      "schema": {
       "type": "object",
       "properties": {
        "errorCode": {
         "type": "string",
         "description": "A code representing the type of error.",
         "example": "Not Found"
        },
        "message": {
         "type": "string",
         "description": "A message describing the error.",
         "example": "Locker group not found"
        }
       },
       "required": [
        "errorCode",
        "message"
       ]
      }
     }
    }
   },
   "parcel_input_200": {
    "description": "Parcel event published successfully",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/input_data_response"
      }
     }
    }
   },
   "parcel_input_400": {
    "description": "The request body could not be parsed, or a field has a value the platform does not accept.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/parcel_input_error"
      },
      "example": {
       "error": "Failed to parse request"
      }
     }
    }
   },
   "parcel_input_500": {
    "description": "The server encountered an internal error.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/parcel_input_error"
      },
      "example": {
       "error": "Internal Server Error"
      }
     }
    }
   },
   "sma_400": {
    "description": "The request is not valid. A required query parameter is missing or blank, a parameter has a value the platform does not accept, or the request body cannot be parsed.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/sma_error"
      },
      "example": {
       "error": "ids parameter is required and should not be blank"
      }
     }
    }
   },
   "sma_500": {
    "description": "The server encountered an internal error.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/sma_error"
      },
      "example": {
       "error": "Internal Server Error"
      }
     }
    }
   },
   "sma_422": {
    "description": "The request is valid, but the platform cannot do it. The requested page is too deep, or parcel locking is not enabled for the carrier.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/sma_error"
      },
      "example": {
       "error": "Parcel lock is not enabled for carrier GLS_AT"
      }
     }
    }
   },
   "sma_provider_error": {
    "description": "The parcel locker provider refused or failed the request. SMA returns the provider's HTTP status (for example 502 or 503) with this body.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/sma_error"
      },
      "example": {
       "error": "Not possible to set parcel lock"
      }
     }
    }
   },
   "sma_404": {
    "description": "The carrier has no open parcel with this ID.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/sma_error"
      },
      "example": {
       "error": "Unable to find shipment [parcelId=1234567890, shipmentId=null]"
      }
     }
    }
   },
   "sma_409": {
    "description": "The parcel has a status that does not allow cancellation, for example because it is already delivered.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/sma_error"
      },
      "example": {
       "error": "Not possible to cancel shipment with status COURIER_DELIVERED."
      }
     }
    }
   },
   "mock_trigger_400": {
    "description": "The request is not valid. For example, the body is not JSON, a required field is missing, or the provider does not support the event. The mock does not send an event.",
    "x-internal": true,
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/MockServiceError"
      }
     }
    }
   },
   "mock_event_query_400": {
    "description": "The ID in the path is empty, for example `GET /parcel/events/`.\nNo event-query route matches that path, so the request reaches the trigger API, which sends this response. The message does not describe the cause. Send a non-empty ID.",
    "x-internal": true,
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/MockServiceError"
      },
      "example": {
       "message": "Invalid JSON in request body"
      }
     }
    }
   },
   "mock_event_query_500": {
    "description": "The mock cannot read its event store. Try again later. The body is a JSON string.",
    "x-internal": true,
    "content": {
     "application/json": {
      "schema": {
       "type": "string",
       "x-internal": true
      },
      "example": "Failed to retrieve locker events"
     }
    }
   }
  }
 }
}
