{
  "openapi": "3.1.0",
  "info": {
    "title": "Shipeezi public read API",
    "version": "1.0.0",
    "description": "The public, unauthenticated read surface of Shipeezi: retail import execution and compliance. It exposes the trace spine that Shipeezi owns, PO line to SSCC carton to booking to container to leg, as a DCSA-shaped track and trace API. Ocean events follow the DCSA Track and Trace taxonomy (event types and the PLANNED / ESTIMATED / ACTUAL classifier); air, road and rail legs use mode-appropriate vocabularies. No key, no signup, no token. Every operation here is a read.",
    "contact": {
      "name": "Shipeezi",
      "email": "sales@shipeezi.com",
      "url": "https://www.shipeezi.com/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.shipeezi.com/legal/terms-of-use"
    }
  },
  "servers": [
    {
      "url": "https://api.shipeezi.com",
      "description": "Production"
    }
  ],
  "security": [],
  "paths": {
    "/api/public/v1/shipments/{reference}": {
      "get": {
        "operationId": "getShipment",
        "summary": "Get a shipment by reference",
        "description": "Resolve one shipment from any reference the carrier accepts (booking reference, bill of lading or container number) and return its legs, containers and events. The reference is matched across the carrier catalog's trackable reference types, so a bill of lading and a container number resolve to the same shipment.",
        "tags": ["shipments"],
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "description": "A shipment reference Shipeezi accepts: the carrier booking reference, the bill of lading number, or the ISO 6346 container number.",
            "schema": {"type": "string", "minLength": 1, "examples": ["MAEU229123456", "SHP-2291"]}
          },
          {
            "name": "referenceType",
            "in": "query",
            "required": false,
            "description": "Force interpretation of the reference when it is ambiguous. Omit to let Shipeezi resolve it.",
            "schema": {"type": "string", "enum": ["bookingReference", "billOfLading", "containerReference", "shipmentReference"]}
          }
        ],
        "responses": {
          "200": {
            "description": "The shipment, resolved.",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Shipment"}
              }
            }
          },
          "404": {
            "description": "No shipment matches that reference.",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"}
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Read RateLimit-Reset before retrying.",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"}
              }
            }
          }
        }
      }
    },
    "/api/public/v1/events": {
      "get": {
        "operationId": "listShipmentEvents",
        "summary": "List events for a shipment",
        "description": "Return the event spine for one shipment, newest first by default. Each event carries its DCSA classifier so a caller can separate what was planned, what is estimated and what actually happened without re-deriving it.",
        "tags": ["events"],
        "parameters": [
          {
            "name": "shipmentReference",
            "in": "query",
            "required": true,
            "description": "The shipment to return events for. Any reference type accepted by getShipment.",
            "schema": {"type": "string", "minLength": 1}
          },
          {
            "name": "eventClassifier",
            "in": "query",
            "required": false,
            "description": "Filter by the DCSA event classifier.",
            "schema": {"type": "string", "enum": ["PLANNED", "ESTIMATED", "ACTUAL"]}
          },
          {
            "name": "eventType",
            "in": "query",
            "required": false,
            "description": "Filter by event type, for example GATE_IN, LOAD, DEPARTURE, ARRIVAL, GATE_OUT.",
            "schema": {"type": "string", "examples": ["DEPARTURE"]}
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum events to return.",
            "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 20}
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from a previous response's nextCursor. A cursor is a position in the ordered list, so an event added mid-pagination cannot make a caller skip or repeat one.",
            "schema": {"type": "string"}
          }
        ],
        "responses": {
          "200": {
            "description": "The events, ordered newest first.",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/EventList"}
              }
            }
          },
          "400": {
            "description": "shipmentReference is missing.",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"}
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"}
              }
            }
          }
        }
      }
    },
    "/api/public/v1/schema": {
      "get": {
        "operationId": "getPublicSchema",
        "summary": "Get the public field catalogue",
        "description": "Return the field catalogue behind this API: the event types and classifiers, the transport modes, the reference types a carrier can be tracked on, and the code lists (UN/LOCODE locations, IMO vessel numbers, ISO 6346 container numbers, SMDG facility codes). Stable, cacheable, and safe to reconcile against a local copy.",
        "tags": ["reference"],
        "responses": {
          "200": {
            "description": "The field catalogue.",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/SchemaCatalogue"}
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Shipment": {
        "type": "object",
        "description": "One shipment: an ordered chain of legs, its containers, and its event spine.",
        "required": ["shipmentReference", "transportMode", "legs"],
        "properties": {
          "shipmentReference": {"type": "string", "description": "The Shipeezi shipment reference."},
          "transportMode": {"$ref": "#/components/schemas/TransportMode"},
          "carrierBookingReference": {"type": "string", "description": "The carrier booking reference for the ocean leg, when the shipment has one."},
          "billOfLading": {"$ref": "#/components/schemas/BillOfLading"},
          "containers": {
            "type": "array",
            "description": "Containers built from one or more bookings.",
            "items": {"$ref": "#/components/schemas/Container"}
          },
          "legs": {
            "type": "array",
            "description": "The ordered leg chain. Multimodal is a sequence of legs on one shipment, never a duplicated shipment.",
            "items": {"$ref": "#/components/schemas/Leg"}
          },
          "events": {
            "type": "array",
            "description": "The shipment's events. The full, pageable set is at /api/public/v1/events.",
            "items": {"$ref": "#/components/schemas/Event"}
          }
        }
      },
      "Leg": {
        "type": "object",
        "description": "One leg of the shipment: a mode, an operator, an ordered position, and its own plan versus actual times.",
        "required": ["legSequence", "mode"],
        "properties": {
          "legSequence": {"type": "integer", "minimum": 1, "description": "Position in the leg chain, starting at 1."},
          "mode": {"$ref": "#/components/schemas/TransportMode"},
          "operator": {"$ref": "#/components/schemas/Operator"},
          "origin": {"$ref": "#/components/schemas/Location"},
          "destination": {"$ref": "#/components/schemas/Location"},
          "vesselVoyage": {"type": "string", "description": "Vessel IMO number and voyage reference for an ocean leg."},
          "plannedDeparture": {"type": "string", "format": "date-time", "description": "Planned departure (DCSA PLANNED)."},
          "estimatedDeparture": {"type": "string", "format": "date-time", "description": "Estimated departure (DCSA ESTIMATED)."},
          "actualDeparture": {"type": "string", "format": "date-time", "description": "Actual departure (DCSA ACTUAL)."},
          "plannedArrival": {"type": "string", "format": "date-time", "description": "Planned arrival."},
          "estimatedArrival": {"type": "string", "format": "date-time", "description": "Estimated arrival."},
          "actualArrival": {"type": "string", "format": "date-time", "description": "Actual arrival."},
          "co2e": {"$ref": "#/components/schemas/Emission"}
        }
      },
      "Event": {
        "type": "object",
        "description": "One event, DCSA-shaped for ocean and mode-appropriate elsewhere. Planned, estimated and actual are the same event type with a different classifier.",
        "required": ["eventType", "eventClassifier", "eventDateTime"],
        "properties": {
          "eventID": {"type": "string", "description": "Stable identifier for this event."},
          "eventType": {"type": "string", "description": "DCSA event type, for example GATE_IN, LOAD, DEPARTURE, ARRIVAL, GATE_OUT."},
          "eventClassifier": {"type": "string", "enum": ["PLANNED", "ESTIMATED", "ACTUAL"], "description": "DCSA classifier."},
          "eventDateTime": {"type": "string", "format": "date-time", "description": "When the event happened, or is planned to."},
          "eventCreatedDateTime": {"type": "string", "format": "date-time", "description": "When Shipeezi recorded the event."},
          "shipmentReference": {"type": "string"},
          "carrierBookingReference": {"type": "string"},
          "containerReference": {"type": "string", "description": "ISO 6346 container number, when the event concerns a container."},
          "mode": {"$ref": "#/components/schemas/TransportMode"},
          "location": {"$ref": "#/components/schemas/Location"},
          "facility": {"type": "object", "description": "The facility, coded with an SMDG code where one applies.", "properties": {
            "facilityCode": {"type": "string"},
            "facilityName": {"type": "string"},
            "unLocationCode": {"type": "string", "description": "UN/LOCODE of the facility's location."}
          }},
          "vessel": {"type": "object", "description": "The vessel, when the event is on an ocean leg.", "properties": {
            "imoNumber": {"type": "string", "description": "IMO vessel number."},
            "vesselName": {"type": "string"}
          }},
          "source": {"type": "string", "description": "Where the event came from: carrier API, forwarder feed, or a scan at the dock."}
        }
      },
      "EventList": {
        "type": "object",
        "required": ["events"],
        "properties": {
          "count": {"type": "integer"},
          "events": {"type": "array", "items": {"$ref": "#/components/schemas/Event"}},
          "nextCursor": {"type": "string", "description": "Pass as cursor to page. Absent when there are no more."}
        }
      },
      "Location": {
        "type": "object",
        "description": "A place, coded the DCSA way.",
        "properties": {
          "unLocationCode": {"type": "string", "description": "UN/LOCODE, for example AUMEL."},
          "locationName": {"type": "string"},
          "countryCode": {"type": "string", "description": "ISO 3166-1 alpha-2."}
        }
      },
      "Operator": {
        "type": "object",
        "description": "The entity operating a leg.",
        "properties": {
          "scac": {"type": "string", "description": "Standard Carrier Alpha Code, where the operator has one."},
          "name": {"type": "string"}
        }
      },
      "Container": {
        "type": "object",
        "description": "A container built from one or more bookings.",
        "properties": {
          "containerReference": {"type": "string", "description": "ISO 6346 container number."},
          "containerType": {"type": "string", "description": "ISO 6346 size and type code."},
          "sealNumber": {"type": "string"}
        }
      },
      "BillOfLading": {
        "type": "object",
        "description": "The bill of lading on the shipment, and any title-chain position.",
        "properties": {
          "number": {"type": "string"},
          "type": {"type": "string", "enum": ["MASTER", "HOUSE", "SWB", "EBL"], "description": "MASTER, HOUSE, sea waybill (SWB) or electronic bill of lading (EBL)."}
        }
      },
      "Emission": {
        "type": "object",
        "description": "CO2e for a leg, carrying the method and the factor version so a number can be reproduced.",
        "properties": {
          "value": {"type": "number", "description": "CO2e in kilograms."},
          "method": {"type": "string", "description": "The calculation method, for example GLEC or ISO 14083."},
          "factorVersion": {"type": "string", "description": "The version of the emission factor set used."}
        }
      },
      "TransportMode": {
        "type": "string",
        "description": "The mode of a leg.",
        "enum": ["SEA", "AIR", "ROAD", "RAIL"]
      },
      "Error": {
        "type": "object",
        "required": ["error", "status"],
        "properties": {
          "error": {"type": "string", "description": "A human-readable message."},
          "status": {"type": "integer", "description": "The HTTP status code, repeated in the body."}
        }
      },
      "SchemaCatalogue": {
        "type": "object",
        "description": "The field catalogue behind this API.",
        "properties": {
          "eventTypes": {"type": "array", "items": {"type": "string"}, "description": "DCSA event types in use."},
          "eventClassifiers": {"type": "array", "items": {"type": "string", "enum": ["PLANNED", "ESTIMATED", "ACTUAL"]}},
          "transportModes": {"type": "array", "items": {"$ref": "#/components/schemas/TransportMode"}},
          "referenceTypes": {
            "type": "array",
            "description": "The reference types a carrier can be tracked on. The carrier catalog decides which one a query is issued with.",
            "items": {"type": "string", "enum": ["bookingReference", "billOfLading", "containerReference", "shipmentReference"]}
          },
          "codeLists": {
            "type": "object",
            "description": "External code lists used across the API.",
            "properties": {
              "locations": {"type": "string", "description": "UN/LOCODE."},
              "vessels": {"type": "string", "description": "IMO vessel numbers."},
              "containers": {"type": "string", "description": "ISO 6346 container numbers."},
              "facilities": {"type": "string", "description": "SMDG facility codes."}
            }
          }
        }
      }
    }
  }
}
