openapi: 3.0.0
info:
  title: Vision API
  version: 1.11.0
  description: >
    ## Introduction


    The Hauler Hero system includes functionality to provide imagery of
    container pickup in the context of each relevant stop or work order. We have
    a lot of customer demand for this feature and, at a macro level, this is a
    unique time for automation technology in general, and the development of
    visual recognition features is well timed to benefit from these advances.


    In order to unlock the tremendous new value of next-generation service
    levels and additional revenue opportunities for our customers, and to
    capitalize on this unique juncture with us, we request our camera management
    partners to provide a specific set of functionality in their video access
    API. The key functionality is listed below.


    ## On-Demand Video API


    ### Access


    We require a video access API to be reachable from the Internet on a public
    IP, subject to proper security controls. It should be a well documented API
    that would accept requests from our cloud computing infrastructure.


    ### Video Source Specification


    It should be straight-forward to specify the source of the video precisely,
    namely:


    * The customer (by name or ID),

    * The specific truck, ideally specified via the same ID as used for work
    order and routing specification already,

    * The camera on that truck, if it has several cameras. We have flexibility
    to utilize commonly understood naming for camera placement, as well as a
    predefined numbering scheme.


    ### Time Range Specification


    We need to be able to provide a time range, specified as a start and an end
    timestamp (ISO format), for the video range to be requested for downloading.
    This would initiate the process of video discovery and preparation for the
    export.


    ### Video Downloading


    Once the video has been requested per specifications above, we would need a
    polling interface to check whether the video has been prepared and is
    available for downloading. This could be a request API endpoint that would
    return a (paginated) list of available videos, based on the filtering
    specifications above. Each element of this list would specify the video
    source and time range of the video, and provide a downloadable link to the
    video (which could be valid temporarily, while giving us ample time to
    download the video).


    ### On-Demand Video Workflow


    1. Hauler Hero calls **POST /video-hero/v1/videos/requests** with customer,
    truck, camera, and time range

    2. Partner begins video discovery and preparation for export

    3. Hauler Hero polls **GET /video-hero/v1/videos** to check whether video is
    prepared and available

    4. Partner returns a paginated list of available videos with downloadable
    links

    5. Hauler Hero downloads the video files using the provided links


    ## Continuous Video API


    Some of our customers would benefit from a continuous video made available
    to them that would show the truck moving along the full length of its route.
    Our system would be able to receive the continuous recordings via an API
    that would yield a paginated list of all continuous recordings (chunked into
    constant time durations) available within a given source and time range
    specification. This API would follow a similar access authorization and
    security, as the on-demand variant of the API.


    ### Continuous Video Workflow


    1. Hauler Hero calls **GET /video-hero/v1/videos/continuous** with source
    and time range filters

    2. Partner returns a paginated list of continuous recordings chunked into
    constant time durations

    3. Hauler Hero downloads the recordings using the provided links


    ## Additional Information Available


    Please reach out to
    [integrations@haulerhero.com](mailto:integrations@haulerhero.com) if you
    have any questions or would like additional clarification.


    ## Authentication


    All requests require an `API-KEY` header for authentication.
servers:
  - url: https://api.yourcompany.com
    description: Partner production server
security:
  - apiKey: []
tags:
  - name: On-Demand Video
    description: >-
      Request and retrieve on-demand video clips for specific stops or work
      orders
  - name: Continuous Video
    description: Access continuous full-route video recordings
paths:
  /video-hero/v1/videos/requests:
    post:
      tags:
        - On-Demand Video
      summary: Request on-demand video
      description: >
        Initiates the process of video discovery and preparation for export.

        Specify the video source (customer, truck, camera) and a time range

        (start and end timestamps in ISO 8601 format) for the video to be
        requested.
      operationId: requestVideo
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoRequest'
            examples:
              basicRequest:
                summary: Request video from a specific truck camera
                value:
                  customerId: 123e4567-e89b-12d3-a456-426614174000
                  truckId: truck-5201
                  cameraId: front
                  startTime: '2026-02-04T08:30:00Z'
                  endTime: '2026-02-04T08:35:00Z'
      responses:
        '202':
          description: Video request accepted and processing has begun
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VideoRequestResponse'
              example:
                success: true
                requestId: req-abc123-def456
                status: processing
                message: >-
                  Video request accepted. Poll GET /video-hero/v1/videos to
                  check availability.
        '400':
          description: Bad request - Invalid parameters or missing required fields
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: INVALID_PAYLOAD
                  message: 'Missing required field: truckId'
        '401':
          description: Unauthorized - Invalid or missing authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: UNAUTHORIZED
                  message: Invalid API key
        '404':
          description: Not found - Customer, truck, or camera not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: NOT_FOUND
                  message: 'Truck not found: truck-5201'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: INTERNAL_ERROR
                  message: >-
                    An unexpected error occurred while processing the video
                    request
  /video-hero/v1/videos:
    get:
      tags:
        - On-Demand Video
      summary: List available videos
      description: >
        Returns a paginated list of available videos based on filtering
        specifications.

        Use this endpoint to poll whether requested videos have been prepared
        and are

        available for downloading. Each element specifies the video source, time
        range,

        and provides a downloadable link (which may be valid temporarily).
      operationId: listVideos
      parameters:
        - name: customerId
          in: query
          required: true
          description: Unique identifier for the customer
          schema:
            type: string
          example: 123e4567-e89b-12d3-a456-426614174000
        - name: truckId
          in: query
          required: false
          description: Filter by truck identifier
          schema:
            type: string
          example: truck-5201
        - name: cameraId
          in: query
          required: false
          description: Filter by camera identifier or placement name
          schema:
            type: string
          example: front
        - name: requestId
          in: query
          required: false
          description: Filter by a specific video request ID
          schema:
            type: string
          example: req-abc123-def456
        - name: startTime
          in: query
          required: false
          description: Filter videos starting from this ISO 8601 timestamp
          schema:
            type: string
            format: date-time
          example: '2026-02-04T08:30:00Z'
        - name: endTime
          in: query
          required: false
          description: Filter videos ending before this ISO 8601 timestamp
          schema:
            type: string
            format: date-time
          example: '2026-02-04T08:35:00Z'
        - name: page
          in: query
          required: false
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
          example: 1
        - name: pageSize
          in: query
          required: false
          description: Number of results per page
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          example: 20
      responses:
        '200':
          description: Videos retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VideoListResponse'
              example:
                success: true
                data:
                  videos:
                    - id: vid-001
                      requestId: req-abc123-def456
                      customerId: 123e4567-e89b-12d3-a456-426614174000
                      truckId: truck-5201
                      cameraId: front
                      startTime: '2026-02-04T08:30:00Z'
                      endTime: '2026-02-04T08:35:00Z'
                      status: ready
                      downloadUrl: >-
                        https://storage.yourcompany.com/videos/vid-001.mp4?token=abc123&expires=1738800000
                      expiresAt: '2026-02-05T08:30:00Z'
                  pagination:
                    page: 1
                    pageSize: 20
                    totalItems: 1
                    totalPages: 1
        '400':
          description: Bad request - Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: INVALID_PAYLOAD
                  message: Invalid customerId format
        '401':
          description: Unauthorized - Invalid or missing authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: UNAUTHORIZED
                  message: Invalid API key
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: INTERNAL_ERROR
                  message: An unexpected error occurred while retrieving videos
  /video-hero/v1/videos/continuous:
    get:
      tags:
        - Continuous Video
      summary: List continuous recordings
      description: >
        Returns a paginated list of all continuous recordings available within a
        given

        source and time range. Recordings are chunked into constant time
        durations.

        This endpoint enables customers to access a continuous video showing the
        truck

        moving along the full length of its route.
      operationId: listContinuousRecordings
      parameters:
        - name: customerId
          in: query
          required: true
          description: Unique identifier for the customer
          schema:
            type: string
          example: 123e4567-e89b-12d3-a456-426614174000
        - name: truckId
          in: query
          required: true
          description: Truck identifier
          schema:
            type: string
          example: truck-5201
        - name: cameraId
          in: query
          required: false
          description: Filter by camera identifier or placement name
          schema:
            type: string
          example: front
        - name: startTime
          in: query
          required: true
          description: Start of time range in ISO 8601 format
          schema:
            type: string
            format: date-time
          example: '2026-02-04T06:00:00Z'
        - name: endTime
          in: query
          required: true
          description: End of time range in ISO 8601 format
          schema:
            type: string
            format: date-time
          example: '2026-02-04T18:00:00Z'
        - name: page
          in: query
          required: false
          description: Page number for pagination
          schema:
            type: integer
            minimum: 1
            default: 1
          example: 1
        - name: pageSize
          in: query
          required: false
          description: Number of results per page
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          example: 20
      responses:
        '200':
          description: Continuous recordings retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContinuousVideoListResponse'
              example:
                success: true
                data:
                  recordings:
                    - id: rec-001
                      customerId: 123e4567-e89b-12d3-a456-426614174000
                      truckId: truck-5201
                      cameraId: front
                      startTime: '2026-02-04T06:00:00Z'
                      endTime: '2026-02-04T06:15:00Z'
                      durationSeconds: 900
                      downloadUrl: >-
                        https://storage.yourcompany.com/continuous/rec-001.mp4?token=xyz789&expires=1738800000
                      expiresAt: '2026-02-05T06:00:00Z'
                    - id: rec-002
                      customerId: 123e4567-e89b-12d3-a456-426614174000
                      truckId: truck-5201
                      cameraId: front
                      startTime: '2026-02-04T06:15:00Z'
                      endTime: '2026-02-04T06:30:00Z'
                      durationSeconds: 900
                      downloadUrl: >-
                        https://storage.yourcompany.com/continuous/rec-002.mp4?token=xyz790&expires=1738800000
                      expiresAt: '2026-02-05T06:00:00Z'
                  pagination:
                    page: 1
                    pageSize: 20
                    totalItems: 48
                    totalPages: 3
        '400':
          description: Bad request - Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: INVALID_PAYLOAD
                  message: 'Invalid time range: startTime must be before endTime'
        '401':
          description: Unauthorized - Invalid or missing authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: UNAUTHORIZED
                  message: Invalid API key
        '404':
          description: Not found - Customer or truck not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: NOT_FOUND
                  message: 'Truck not found: truck-5201'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  code: INTERNAL_ERROR
                  message: An unexpected error occurred while retrieving recordings
components:
  schemas:
    VideoRequest:
      type: object
      required:
        - customerId
        - truckId
        - cameraId
        - startTime
        - endTime
      properties:
        customerId:
          type: string
          description: Unique identifier or name for the customer
          example: 123e4567-e89b-12d3-a456-426614174000
        truckId:
          type: string
          description: >-
            Truck identifier, ideally the same ID used for work order and
            routing specification
          example: truck-5201
        cameraId:
          type: string
          description: |
            Camera identifier on the truck. Can use commonly understood naming
            for camera placement (e.g., "front", "rear", "left", "right") or
            a predefined numbering scheme (e.g., "1", "2", "3").
          example: front
        startTime:
          type: string
          format: date-time
          description: Start of the requested video time range in ISO 8601 format
          example: '2026-02-04T08:30:00Z'
        endTime:
          type: string
          format: date-time
          description: End of the requested video time range in ISO 8601 format
          example: '2026-02-04T08:35:00Z'
    VideoRequestResponse:
      type: object
      required:
        - success
        - requestId
        - status
      properties:
        success:
          type: boolean
          description: Whether the request was accepted
          example: true
        requestId:
          type: string
          description: Unique identifier for the video request, used for polling status
          example: req-abc123-def456
        status:
          type: string
          description: Current status of the video request
          enum:
            - processing
            - ready
            - failed
          example: processing
        message:
          type: string
          description: Human-readable status message
          example: >-
            Video request accepted. Poll GET /video-hero/v1/videos to check
            availability.
    Video:
      type: object
      required:
        - id
        - customerId
        - truckId
        - cameraId
        - startTime
        - endTime
        - status
      properties:
        id:
          type: string
          description: Unique identifier for the video
          example: vid-001
        requestId:
          type: string
          description: The request ID that initiated this video preparation
          example: req-abc123-def456
        customerId:
          type: string
          description: Customer identifier
          example: 123e4567-e89b-12d3-a456-426614174000
        truckId:
          type: string
          description: Truck identifier
          example: truck-5201
        cameraId:
          type: string
          description: Camera identifier
          example: front
        startTime:
          type: string
          format: date-time
          description: Start time of the video clip
          example: '2026-02-04T08:30:00Z'
        endTime:
          type: string
          format: date-time
          description: End time of the video clip
          example: '2026-02-04T08:35:00Z'
        status:
          type: string
          description: Current status of the video
          enum:
            - processing
            - ready
            - expired
            - failed
          example: ready
        downloadUrl:
          type: string
          format: uri
          description: >
            Temporarily valid URL for downloading the video file.

            Only present when status is "ready". Ample time is provided for
            downloading.
          example: >-
            https://storage.yourcompany.com/videos/vid-001.mp4?token=abc123&expires=1738800000
        expiresAt:
          type: string
          format: date-time
          description: Timestamp when the download URL expires
          example: '2026-02-05T08:30:00Z'
    ContinuousRecording:
      type: object
      required:
        - id
        - customerId
        - truckId
        - cameraId
        - startTime
        - endTime
        - durationSeconds
        - downloadUrl
      properties:
        id:
          type: string
          description: Unique identifier for the recording chunk
          example: rec-001
        customerId:
          type: string
          description: Customer identifier
          example: 123e4567-e89b-12d3-a456-426614174000
        truckId:
          type: string
          description: Truck identifier
          example: truck-5201
        cameraId:
          type: string
          description: Camera identifier
          example: front
        startTime:
          type: string
          format: date-time
          description: Start time of this recording chunk
          example: '2026-02-04T06:00:00Z'
        endTime:
          type: string
          format: date-time
          description: End time of this recording chunk
          example: '2026-02-04T06:15:00Z'
        durationSeconds:
          type: integer
          description: Duration of this recording chunk in seconds
          example: 900
        downloadUrl:
          type: string
          format: uri
          description: Temporarily valid URL for downloading the recording
          example: >-
            https://storage.yourcompany.com/continuous/rec-001.mp4?token=xyz789&expires=1738800000
        expiresAt:
          type: string
          format: date-time
          description: Timestamp when the download URL expires
          example: '2026-02-05T06:00:00Z'
    Pagination:
      type: object
      properties:
        page:
          type: integer
          description: Current page number
          example: 1
        pageSize:
          type: integer
          description: Number of items per page
          example: 20
        totalItems:
          type: integer
          description: Total number of items across all pages
          example: 48
        totalPages:
          type: integer
          description: Total number of pages
          example: 3
    VideoListResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          description: Whether the request was successful
          example: true
        data:
          type: object
          properties:
            videos:
              type: array
              description: List of available videos
              items:
                $ref: '#/components/schemas/Video'
            pagination:
              $ref: '#/components/schemas/Pagination'
    ContinuousVideoListResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          description: Whether the request was successful
          example: true
        data:
          type: object
          properties:
            recordings:
              type: array
              description: List of continuous recording chunks
              items:
                $ref: '#/components/schemas/ContinuousRecording'
            pagination:
              $ref: '#/components/schemas/Pagination'
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          description: Always false for errors
          example: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code
              example: INVALID_PAYLOAD
              enum:
                - INVALID_PAYLOAD
                - UNAUTHORIZED
                - INTERNAL_ERROR
                - NOT_FOUND
            message:
              type: string
              description: Human-readable error message
              example: 'Missing required field: truckId'
            details:
              type: object
              description: Additional error details (optional)
              additionalProperties: true
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: API-KEY
      description: |
        API key for authenticating requests.

        To obtain an API key:
        - Contact your account manager
        - Email: integrations@haulerhero.com

        Include in request header: `API-KEY: your_api_key_here`
