openapi: 3.1.0
info:
  title: Terminal49 Schedules — DCSA Commercial Schedules API
  version: 1.0.3
  description: |
    DCSA Commercial Schedules 1.0.3 projections for vessel and port schedules.
    The `/v1` API currently requires no authentication.

    Source timestamps do not include timezone offsets. Responses normalize them
    to RFC 3339 by appending `Z` without port-timezone conversion; missing times
    use `T00:00:00Z`.

    Cut-off times, terminal/facility codes, and universal service references
    are omitted when unavailable. Point-to-point routing is not implemented,
    and no 8–10 week coverage guarantee is made.
servers:
  - url: https://good-spaniel-762.convex.site
paths:
  /v1/vessel-schedules:
    get:
      operationId: getVesselSchedules
      summary: Get vessel schedules
      description: |
        At least one supported schedule filter is required:
        `carrierServiceCode`, `vesselIMONumber`, or `UNLocationCode`.
        `responseScope` defaults to `FULL_VOYAGE`.
      parameters:
        - $ref: "#/components/parameters/ApiVersion"
        - name: carrierServiceCode
          in: query
          schema:
            type: string
            maxLength: 11
          example: TPI
        - name: vesselIMONumber
          in: query
          schema:
            type: string
            pattern: '^\d{7,8}$'
          example: "9200706"
        - name: UNLocationCode
          in: query
          schema:
            type: string
            pattern: '^[A-Z]{2}[A-Z2-9]{3}$'
          example: USNYC
        - name: startDate
          in: query
          schema:
            type: string
            format: date
        - name: endDate
          in: query
          schema:
            type: string
            format: date
        - name: responseScope
          in: query
          schema:
            type: string
            enum: [FULL_VOYAGE, MATCHED_CALLS]
            default: FULL_VOYAGE
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: DCSA ServiceSchedule objects
          headers:
            API-Version:
              $ref: "#/components/headers/ApiVersion"
            Next-Page-Cursor:
              $ref: "#/components/headers/NextPageCursor"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ServiceSchedule"
        "400":
          $ref: "#/components/responses/Error"
        "500":
          $ref: "#/components/responses/Error"
  /v1/port-schedules:
    get:
      operationId: getPortSchedules
      summary: Get port schedules
      parameters:
        - $ref: "#/components/parameters/ApiVersion"
        - name: UNLocationCode
          in: query
          required: true
          schema:
            type: string
            pattern: '^[A-Z]{2}[A-Z2-9]{3}$'
          example: USNYC
        - name: date
          in: query
          required: true
          schema:
            type: string
            format: date
          example: "2026-08-20"
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: DCSA PortSchedule objects
          headers:
            API-Version:
              $ref: "#/components/headers/ApiVersion"
            Next-Page-Cursor:
              $ref: "#/components/headers/NextPageCursor"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/PortSchedule"
        "400":
          $ref: "#/components/responses/Error"
        "500":
          $ref: "#/components/responses/Error"
components:
  parameters:
    ApiVersion:
      name: API-Version
      in: header
      required: false
      description: Optional URI-aligned major API version.
      schema:
        type: string
        enum: ["1"]
    Limit:
      name: limit
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 100
    Cursor:
      name: cursor
      in: query
      required: false
      schema:
        type: string
        maxLength: 1024
  headers:
    ApiVersion:
      description: Full contract version returned by the server.
      schema:
        type: string
        example: 1.0.3
    NextPageCursor:
      description: Opaque cursor for the next page. Omitted on the final page.
      schema:
        type: string
        maxLength: 1024
  responses:
    Error:
      description: DCSA CS ErrorResponse
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
  schemas:
    Timestamp:
      type: object
      required: [eventTypeCode, eventClassifierCode, eventDateTime]
      properties:
        eventTypeCode:
          type: string
          enum: [ARRI, DEPA]
        eventClassifierCode:
          type: string
          enum: [EST]
        eventDateTime:
          type: string
          format: date-time
    Vessel:
      type: object
      properties:
        vesselIMONumber:
          type: string
        MMSINumber:
          type: string
        name:
          type: string
        operatorCarrierCode:
          type: string
        operatorCarrierCodeListProvider:
          type: string
          enum: [NMFTA]
    TransportCall:
      type: object
      required:
        - transportCallReference
        - carrierImportVoyageNumber
        - timestamps
      properties:
        transportCallReference:
          type: string
        carrierImportVoyageNumber:
          type: string
        location:
          type: object
          properties:
            UNLocationCode:
              type: string
        timestamps:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/Timestamp"
    VesselSchedule:
      type: object
      required: [isDummyVessel, transportCalls]
      properties:
        vessel:
          $ref: "#/components/schemas/Vessel"
        isDummyVessel:
          type: boolean
        transportCalls:
          type: array
          items:
            $ref: "#/components/schemas/TransportCall"
    ServiceSchedule:
      type: object
      required:
        - carrierServiceName
        - carrierServiceCode
        - vesselSchedules
      properties:
        carrierServiceName:
          type: string
        carrierServiceCode:
          type: string
        vesselSchedules:
          type: array
          items:
            $ref: "#/components/schemas/VesselSchedule"
    ServicePartnerSchedule:
      type: object
      required:
        - carrierServiceName
        - carrierServiceCode
        - carrierImportVoyageNumber
        - carrierExportVoyageNumber
      properties:
        carrierCode:
          type: string
        carrierCodeListProvider:
          type: string
          enum: [NMFTA]
        carrierServiceName:
          type: string
        carrierServiceCode:
          type: string
        carrierImportVoyageNumber:
          type: string
        carrierExportVoyageNumber:
          type: string
    PortVesselSchedule:
      type: object
      required: [servicePartners, isDummyVessel, timestamps]
      properties:
        servicePartners:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/ServicePartnerSchedule"
        vessel:
          $ref: "#/components/schemas/Vessel"
        isDummyVessel:
          type: boolean
        timestamps:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/Timestamp"
    PortSchedule:
      type: object
      required: [location, vesselSchedules]
      properties:
        location:
          type: object
          required: [UNLocationCode]
          properties:
            locationName:
              type: string
            UNLocationCode:
              type: string
        vesselSchedules:
          type: array
          items:
            $ref: "#/components/schemas/PortVesselSchedule"
    DetailedError:
      type: object
      required: [errorCodeText, errorCodeMessage]
      properties:
        errorCode:
          type: integer
        property:
          type: string
        value:
          type: string
        errorCodeText:
          type: string
        errorCodeMessage:
          type: string
    ErrorResponse:
      type: object
      required:
        - httpMethod
        - requestUri
        - statusCode
        - statusCodeText
        - errorDateTime
        - errors
      properties:
        httpMethod:
          type: string
        requestUri:
          type: string
        statusCode:
          type: integer
        statusCodeText:
          type: string
        statusCodeMessage:
          type: string
        errorDateTime:
          type: string
          format: date-time
        errors:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/DetailedError"
