openapi: 3.1.0
info:
  x-api-id: 686fc029-1611-4eb5-996c-ebf1462659c6
  x-audience:
    - external-partner
  title: Conundra Resources API
  version: 1.27.2
  description: |
    The Resources API provides the resources necessary to create a planning.
  contact:
    name: API support
    url: https://servicedesk.conundra.eu
servers:
  - url: https://api.conundra.eu/resource-management/v1
    description: Resources API Production
security:
  - clientCredentials: []
tags:
  - name: health
    x-displayName: Health check
    description: Miscellaneous endpoints for general API functionality
  - name: employee
    x-displayName: Employee
    description: >
      Endpoints used for managing the general information regarding your
      `Employees`. These endpoints are meant for managing `Employees` whose role
      is relevant

      for the functionality in Resource Management, ie: typically only those
      `Employees` capable of operating `TransportResources`.
    externalDocs:
      description: Find out more
      url: >-
        https://developer.conundra.eu/developer-portal/resource-management/domain/#employee
  - name: shift-schedule
    x-displayName: Shift Schedule
    description: >
      `ShiftSchedules` can be used to describe the recurring pattern for an
      `Employee`'s availability. They do not trigger availabilities themselves,
      but can be 

      used to generate availabilities according to this schedule, through the
      application's user interface.


      Providing `ShiftSchedules` enables planners to do long-term planning using
      the _Employee Overview_ in the UI, since this allows us to predict when an
      `Employee`

      _should_ be available.
    externalDocs:
      description: Find out more
      url: >-
        https://developer.conundra.eu/developer-portal/resource-management/domain/#shift-schedule
  - name: actual
    x-displayName: Actual
    description: >
      `Actuals` capture the worked hours for an `Employee` during a completed
      work shift. This data is used to provide insights into actual worked hours
      compared

      to contractual hours, and also helps steer the optimization algorithm
      towards creating a balanced work week that fulfills contractual hours
      without significant

      undershooting or overshooting.   


      By their nature, `Actuals` should always represent completed work shifts
      and therefore should always be in the past, adding

      `Actuals` that end in the future could lead to undesired behaviour.
  - name: availability
    x-displayName: Availability
    description: >
      `Availabilities` define a specific time range during which an `Employee`
      is available to execute tasks.

      These can either be derived from a `ShiftSchedule` (via the user
      interface) or created on an ad-hoc basis.


      When an `Availability` is created or updated, it triggers a consolidation
      process that generates a snapshot of the corresponding `Employee` at that
      moment, referred to as an `AvailableEmployee`.

      This snapshot accounts for relocations (managed through the user
      interface) and `Unavailabilities`, ensuring a single source of truth for
      the `Employee`'s status at that point in time.


      Any modifications to this `AvailableEmployee` snapshot activate an
      algorithm that evaluates potential `ResourceCombinations` involving the
      `Employee`'s `Availability`.

      During this evaluation, potential `TransportResources` are assessed.

      If the heuristic identifies that a specific `ResourceCombination` would
      enhance the overall solution's fitness, it is either created or updated.
    externalDocs:
      description: Find out more
      url: >-
        https://developer.conundra.eu/developer-portal/resource-management/domain/#availability
  - name: employee-unavailability
    x-displayName: Unavailability [EXPERIMENTAL]
    description: >
      `Unavailabilities` define a specific time range during which an `Employee`
      is unavailable to execute tasks.

      This can be due to sickness, holiday, or other temporary absences.

      During its duration, the employee can not be matched with a transport
      resource and used as part of the planning.
  - name: transport-resource
    x-displayName: Transport Resource
    description: >
      Endpoints used for managing the general information regarding your
      `Transport Resources`.

      These can be `Trucks`, `Trailers` and `Tractors`.
  - name: transport-resource-unavailability
    x-displayName: Unavailability [EXPERIMENTAL]
    description: >
      `Unavailabilities` define a specific time range during which a
      `TransportResource` is unavailable.

      This can be due to, for example, technical issues.

      During its duration, the `TransportResource` can not be matched with an
      available `Employee` and used as part of the planning.
  - name: homebase
    x-displayName: Home Base [EXPERIMENTAL]
    description: >
      A `Home Base` is a reusable address that is used to specify the location
      of `Employees` or `Transport Resources`.

      Instead of specifying a full address for each of these, the user can
      create a single reusable `HomeBase` and assign it to all.


      Updates to an assigned `HomeBase` are propagated to all future resources
      using it.
  - name: forecast
    x-displayName: Forecast [EXPERIMENTAL]
    description: >
      A forecast is the expected the number of shifts that will be required on
      the given day and location.

      They is used in the context of capacity planning: a difference in the
      forecast and the available shifts can indicate ue in the planning.

      The provided forecasts are only used to show to the end user and are not
      taken into account for any of the calculations made by the application.
  - name: deployment
    x-displayName: Deployment [EXPERIMENTAL]
    description: >
      Endpoints used for managing `Deployments`. A `Deployment` represents the
      actual assignment of an `Employee` to one or more `TransportResources` 

      for a specific time period and location. External deployments can be
      created to represent work assignments that are managed outside of the 

      Resource Management system. Releasing or unreleasing routes in PTV
      OptiFlow also manages `Deployments`. 

      These `Deployments` are managed internally by Resource Management and
      cannot be modified by this API.
x-tagGroups:
  - name: Health
    tags:
      - health
  - name: Employee Management
    tags:
      - employee
      - shift-schedule
      - availability
      - employee-unavailability
  - name: Transport Resource Management
    tags:
      - transport-resource
      - transport-resource-unavailability
  - name: Location Management
    tags:
      - homebase
  - name: Forecasts
    tags:
      - forecast
  - name: Deployments
    tags:
      - deployment
  - name: Means
    tags:
      - actual
paths:
  /ping:
    get:
      tags:
        - health
      summary: Health check
      description: >
        The `ping`-endpoint can be used for validating a connection with the
        application. It will authenticate the caller and respond `pong` if
        everything is set-up correctly.
      operationId: ping
      responses:
        '200':
          description: >-
            Returned when the application is responsive and you are
            authenticated.
          content:
            text/plain:
              schema:
                type: string
              example: pong
        '401':
          $ref: '#/components/responses/401'
  /employee:
    get:
      operationId: getPagedEmployees
      tags:
        - employee
      summary: Get cursor-based employees
      description: >
        Retrieve employees in bulk using cursor-based paging (see the
        Cursor-based pagination documentation on the PTV Developer Portal).
      parameters:
        - in: query
          name: cursor
          schema:
            type: string
          required: false
          description: >
            The cursor of the page to return. No cursor is expected for the
            initial request. The cursors returned by this endpoint can be used
            for subsequent requests.
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          required: false
          description: |
            Number of results to return per page.
      responses:
        '200':
          description: >-
            The results for the current paged request and optional pointers to
            related result pages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPagedEmployees'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
  /employee/{business_id}:
    put:
      tags:
        - employee
      summary: Upsert Employee
      operationId: upsertEmployee
      description: >
        Create or update an `Employee`. A unique ID (`business_id`) is required
        to identify the `Employee`. Calling this endpoint with an existing
        `business_id` 

        will update the `Employee`. 


        Modifying (or retrieving) an `Employee` will provide the caller with a
        version number for this `Employee`. This version can be passed to the
        _upsert_ endpoint

        as a _weak ETag_ in the `If-Match` header. This allows the caller to
        ensure that the `Employee` has not been modified since the last time it
        was retrieved.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >-
            Unique identifier for this `Employee`. Should only contain
            characters which do not need URL encoding.
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Employee'
      responses:
        '201':
          description: Employee created or updated
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Employee'
        '204':
          description: Employee created or updated
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '409':
          $ref: '#/components/responses/409'
        '412':
          $ref: '#/components/responses/412'
    get:
      tags:
        - employee
      operationId: getEmployee
      summary: Get Employee
      description: Get an existing Employee, defined by their `business_id`.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: |
            The unique ID (`business_id`) used to create this `Employee`.
      responses:
        '200':
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
          description: >
            The `Employee` was successfully retrieved. Details are in the
            response body.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Employee'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - employee
      operationId: deleteEmployee
      summary: Delete Employee
      description: >
        Delete an Employee, defined by their `business_id`. Removing an
        `Employee` will remove all related sub-resources. 


        **Note:** Deployed `ResourceCombinations` (eg: used in a released route
        in an optimization) will not be removed.
      parameters:
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: >
            Deletion has succeeded and body is empty. Sub-resources will be
            removed asynchronously.
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
  /employee/{business_id}/availability:
    get:
      tags:
        - availability
      operationId: getEmployeeAvailabilities
      summary: Get all Employee Availabilities
      description: >
        Retrieves all `Availabilities` for a single `Employee` (identified by
        their `business_id`) within an optional time range. 


        This endpoint will return any **overlapping** `Availability`, so it is
        possible for the returned `Availability` to have a time range that
        spills outside 

        of the provided time range. Overlap is determined for the widest
        possible range on an `Availability, ie: `earliest_start` up until
        (calculated) `latest_stop`.


        When providing a time range, it can be open (either `from` or `until` is
        provided) or closed (both `from` and `until` are provided).
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >
            The unique identifier of the `Employee` for whom to retrieve
            `Availabilities`.
        - in: query
          name: from
          schema:
            type: string
            format: date-time
          example: '2021-01-01T10:15:30Z'
          required: false
          description: >
            The start of the time range to retrieve `Availabilities` for. If not
            provided, the time range will be open-ended, starting from the
            earliest `Availability` for this `Employee`.
        - in: query
          name: until
          schema:
            type: string
            format: date-time
          example: '2021-01-05T10:15:30Z'
          required: false
          description: >
            The end of the time range to retrieve `Availabilities` for. If not
            provided, the time range will be open-ended, ending at the latest
            `Availability` for this `Employee`.


            If both `from` and `until` are provided, until must not be lower
            than `from`.
      responses:
        '200':
          description: >
            `Employee` `Availabilities` that overlap with the provided time
            range. This list can be empty. Each item contains the
            `Availability`'s `version` for

            optimistic locking purposes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availabilities'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
          description: |
            The `Employee` was not found.
    post:
      tags:
        - availability
      summary: Create Employee Availability
      operationId: addEmployeeAvailability
      description: >
        Add an `Availability` for an `Employee`. An identifier will be generated
        by the application. This identifier can be retrieved from the `Location`
        header, 

        or response body (if the `Prefer` header is set to
        `return=representation`).


        New `Availabilities` should not overlap with existing `Availabilities`.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >
            The unique identifier of the `Employee` for whom to create an
            `Availability`.
        - $ref: '#/components/parameters/prefer'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Availability'
      responses:
        '201':
          description: Availability created.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availability'
        '204':
          description: Availability created
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '409':
          $ref: '#/components/responses/409'
          description: >
            A conflict occurs when the `Availability` overlaps with an existing
            `Availability`. There should be no overlap between availabilities,
            since this could

            lead to overlapping deployments of the same `Employee`.
    delete:
      tags:
        - availability
      operationId: deleteEmployeeAvailabilities
      summary: Delete Employee Availabilities
      description: >
        Delete all existing `Employee` `Availabilities` that overlap using an
        open or closed a time range. Overlap is determined for the widest
        possible range on 

        an `Availability, ie: `earliest_start` up until (calculated)
        `latest_stop`. 


        **Note:** Any **overlapping** `Availabilities will be removed, an
        `Availability` can be partially outside of the provided time range.
      parameters:
        - $ref: '#/components/parameters/business_id'
        - in: query
          name: from
          schema:
            type: string
            format: date-time
          example: '2021-01-01T10:15:30Z'
          required: false
        - in: query
          name: until
          schema:
            type: string
            format: date-time
          example: '2021-01-05T10:15:30Z'
          required: false
      responses:
        '204':
          description: |
            Deletion has succeeded and body is empty
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
  /employee/{business_id}/availability/{generated_id}:
    get:
      tags:
        - availability
      operationId: getEmployeeAvailability
      summary: Get Employee Availability
      description: >
        Retrieve an existing `Availability`, identified by its `generated_id`,
        for an `Employee`, identified by their `business_id`.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >
            The unique identifier of the `Employee` for whom to retrieve an
            `Availability`.
        - $ref: '#/components/parameters/generated_id'
          description: |
            The unique identifier of the `Availability` to retrieve.
      responses:
        '200':
          description: Employee Availability is retrieved
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availability'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
          description: >
            No `Availability` found with this `generated_id` for the specified
            `Employee`.
    put:
      tags:
        - availability
      operationId: updateEmployeeAvailability
      summary: Update Employee Availability
      description: >
        Update a specific `Availability`, identified by its `generated_id`, for
        an `Employee`, identified by their `business_id`. The updated
        `Availability` should

        not overlap with existing `Availabilities`.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >
            The unique identifier of the `Employee` for whom to update an
            `Availability`.
        - $ref: '#/components/parameters/generated_id'
          description: |
            The unique identifier of the `Availability` to update.
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Availability'
      responses:
        '201':
          description: Availability updated.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Availability'
        '204':
          description: Availability updated.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
    delete:
      tags:
        - availability
      operationId: deleteEmployeeAvailability
      summary: Delete Employee Availability by id
      description: >
        Delete an existing `Availability`, identified by its `generated_id`, for
        an `Employee`, identified by their `business_id`. This will remove a
        `ResourceCombination`

        tied to this `Availability` if it was not deployed by releasing a route
        in an optimization.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >
            The unique identifier of the `Employee` for whom to delete an
            `Availability`.
        - $ref: '#/components/parameters/generated_id'
          description: |
            The unique identifier of the `Availability` to delete.
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: |
            Deletion has succeeded and body is empty
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
  /employee/{business_id}/unavailability:
    post:
      tags:
        - employee-unavailability
      summary: '[EXPERIMENTAL] Create Employee Unavailability'
      operationId: createEmployeeUnavailability
      description: Create an unavailability for an employee
      parameters:
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/prefer'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployeeUnavailability'
      responses:
        '201':
          description: Employee Unavailability created
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployeeUnavailability'
        '204':
          description: Employee Unavailability created
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
    get:
      tags:
        - employee-unavailability
      summary: '[EXPERIMENTAL] Get all Employee Unavailabilities by Employee business id'
      description: >
        Get all Employee Unavailabilities by Employee business id. When a `from`
        and `until` are provided, we match any `Unavailabilities` that overlap
        with this range.
      operationId: getEmployeeUnavailabilities
      parameters:
        - $ref: '#/components/parameters/business_id'
        - in: query
          name: from
          schema:
            type: string
            format: date-time
          example: '2021-01-01T10:15:30Z'
          required: false
        - in: query
          name: until
          schema:
            type: string
            format: date-time
          example: '2021-01-05T10:15:30Z'
          required: false
      responses:
        '200':
          description: Employee Unavailabilities are retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployeeUnavailabilities'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
  /employee/{business_id}/unavailability/{generated_id}:
    put:
      tags:
        - employee-unavailability
      summary: '[EXPERIMENTAL] Upsert Employee Unavailability'
      description: Create or update an unavailability for an employee.
      operationId: upsertEmployeeUnavailability
      parameters:
        - $ref: '#/components/parameters/generated_id'
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployeeUnavailability'
      responses:
        '201':
          description: Employee Unavailability created or updated.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployeeUnavailability'
        '204':
          description: Employee Unavailability created or updated.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - employee-unavailability
      summary: '[EXPERIMENTAL] Delete Employee Unavailability by id'
      operationId: deleteEmployeeUnavailability
      parameters:
        - $ref: '#/components/parameters/generated_id'
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: Employee Unavailability deleted
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
    get:
      tags:
        - employee-unavailability
      summary: '[EXPERIMENTAL] Get Employee Unavailability by id'
      operationId: getEmployeeUnavailability
      parameters:
        - $ref: '#/components/parameters/generated_id'
        - $ref: '#/components/parameters/business_id'
      responses:
        '200':
          description: Employee Unavailability retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployeeUnavailability'
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
  /employee/{business_id}/shift-schedule:
    post:
      tags:
        - shift-schedule
      summary: Create Shift Schedule
      operationId: createShiftSchedule
      description: >
        Endpoint to create a `ShiftSchedule`. An identifier will be generated by
        the application. This identifier can be retrieved from the `Location`
        header, or 

        response body (if the `Prefer` header is set to
        `return=representation`).
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: |
            The business id of the `Employee` to create a `ShiftSchedule` for.
        - $ref: '#/components/parameters/prefer'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ShiftSchedule'
      responses:
        '201':
          description: Shift Schedule created
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShiftSchedule'
        '204':
          description: Shift Schedule created
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
            ETag:
              $ref: '#/components/headers/ETag'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
          description: >
            A `Not Found` is triggered on creation, if the `Employee` does not
            exist.
        '409':
          $ref: '#/components/responses/409'
          description: >
            A conflict occurs when the `ShiftSchedule` overlaps with an existing
            `ShiftSchedule`. 


            **Note:** Since there is no end date on a `ShiftSchedule`, it is
            only possible to create 1 `ShiftSchedule`. Trying to add a second
            one will always 

            overlap with the existing one. 
    get:
      tags:
        - shift-schedule
      summary: Get all Shift Schedules by Employee
      operationId: getShiftSchedulesByEmployeeId
      description: >
        Retrieve all `ShiftSchedules` for a given `Employee`, identified by
        their business id.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: |
            The business id of the `Employee` to retrieve `ShiftSchedules` for.
      responses:
        '200':
          description: >
            Known `ShiftSchedules` for the `Employee`. List may be empty if no
            `ShiftSchedules` were found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShiftSchedules'
        '401':
          $ref: '#/components/responses/401'
        '404':
          description: >
            A `Not Found` is triggered on retrieval, if the `Employee` does not
            exist.
          $ref: '#/components/responses/404'
  /employee/{business_id}/shift-schedule/{generated_id}:
    put:
      tags:
        - shift-schedule
      summary: Update Shift Schedule
      operationId: updateShiftSchedule
      description: >
        Update an existing `ShiftSchedule` for an `Employee`. 


        The `generated_id` is determined by the application and was returned on
        creation. A list of existing `ShiftSchedules` can be retrieved by using
        the 

        `getShiftSchedulesByEmployeeId` endpoint.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >
            The business id of the `Employee` to update this `ShiftSchedule`
            for.
        - $ref: '#/components/parameters/generated_id'
          description: |
            The `generated_id` of the `ShiftSchedule` to update.
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ShiftSchedule'
      responses:
        '201':
          description: Shift Schedule updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShiftSchedule'
        '204':
          description: Shift Schedule updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
            ETag:
              $ref: '#/components/headers/ETag'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
          description: >
            A `Not Found` is triggered on retrieval, if either the `Employee` or
            the `ShiftSchedule` does not exist.
        '412':
          $ref: '#/components/responses/412'
    delete:
      tags:
        - shift-schedule
      summary: Delete Shift Schedule
      operationId: deleteShiftSchedule
      description: >
        Update an existing `ShiftSchedule` for an `Employee`.


        The `generated_id` is determined by the application and was returned on
        creation. A list of existing `ShiftSchedules` can be retrieved by using
        the

        `getShiftSchedulesByEmployeeId` endpoint.
      parameters:
        - $ref: '#/components/parameters/business_id'
          description: >
            The business id of the `Employee` to delete this `ShiftSchedule`
            for.
        - $ref: '#/components/parameters/generated_id'
          description: |
            The `generated_id` of the `ShiftSchedule` to delete.
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: |
            Deletion has succeeded and body is empty
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
  /transport-resource:
    get:
      operationId: getPagedTransportResources
      tags:
        - transport-resource
      summary: Get cursor-based transport resources
      description: >
        Retrieve transport resources in bulk using cursor-based paging (see the
        Cursor-based pagination documentation on the PTV Developer Portal).
      parameters:
        - in: query
          name: cursor
          schema:
            type: string
          required: false
          description: >
            The cursor of the page to return. No cursor is expected for the
            initial request. The cursors returned by this endpoint can be used
            for subsequent requests.
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          required: false
          description: |
            Number of results to return per page.
      responses:
        '200':
          description: >-
            The results for the current paged request and optional pointers to
            related result pages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPagedTransportResources'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
  /transport-resource/{business_id}:
    put:
      tags:
        - transport-resource
      summary: Upsert Transport Resource
      operationId: upsertTransportResource
      description: >
        Upsert a single `TransportResource`.


        As a `TransportResource` is considered to be always available unless a
        `TransportResourceUnavailability` says otherwise, its presence will
        result in the

        application trying to create `ResourceCombinations` by matching
        `AvailableEmployees` with this `TransportResource`.
      parameters:
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransportResource'
      responses:
        '201':
          description: Transport Resource created or updated
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportResource'
        '204':
          description: Transport Resource created or updated
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
    get:
      tags:
        - transport-resource
      operationId: getTransportResource
      summary: Get Transport Resource by business id
      description: Get an existing `TransportResource`
      parameters:
        - $ref: '#/components/parameters/business_id'
      responses:
        '200':
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
          description: Transport Resource is retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportResource'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - transport-resource
      operationId: deleteTransportResource
      summary: Delete Transport Resource by business id
      description: >
        Delete an existing `TransportResource`.


        Upon deleting, the application will also remove ResourceCombinations
        using this TransportResource and try to find replacements.

        All unavailabilities and relocations related to this TransportResource
        will be removed as well.
      parameters:
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: |
            Deletion has succeeded and body is empty
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
  /transport-resource/{business_id}/unavailability:
    post:
      tags:
        - transport-resource-unavailability
      summary: '[EXPERIMENTAL] Create TransportResource Unavailability'
      description: >
        This endpoint allows you to create an `Unavailability` with a generated
        ID. This can be used for _ad hoc_ 

        `Unavailabilities` or situations where the source system does not
        contain any unique IDs.


        See the PUT operation for more information on the functional impact of
        adding a new unavailability.
      operationId: addTransportResourceUnavailability
      parameters:
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/prefer'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransportResourceUnavailability'
      responses:
        '201':
          description: Unavailability created.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportResourceUnavailability'
        '204':
          description: Unavailability created
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    get:
      tags:
        - transport-resource-unavailability
      summary: >-
        [EXPERIMENTAL] Get all TransportResource Unavailabilities by
        TransportResource business id
      description: >
        Get all TransportResource Unavailabilities by TransportResource business
        id. When a `from` and `until` are provided, we match any
        `Unavailabilities` that overlap with this range.
      operationId: getTransportResourceUnavailabilities
      parameters:
        - $ref: '#/components/parameters/business_id'
        - in: query
          name: from
          schema:
            type: string
            format: date-time
          example: '2021-01-01T10:15:30Z'
          required: false
        - in: query
          name: until
          schema:
            type: string
            format: date-time
          example: '2021-01-05T10:15:30Z'
          required: false
      responses:
        '200':
          description: Transport Resource is retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportResourceUnavailabilities'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
  /transport-resource/{business_id}/unavailability/{generated_id}:
    put:
      tags:
        - transport-resource-unavailability
      summary: '[EXPERIMENTAL] Upsert TransportResource Unavailability'
      description: >
        Create or update a `TransportResourceUnavailability`.


        When a `TransportResource` becomes unavailable, the
        `ResourceCombinations` whose guaranteed working time overlapped with the
        unavailability are deleted.

        For other overlaps the existing combinations are only re-evaluated.
      operationId: upsertTransportResourceUnavailability
      parameters:
        - $ref: '#/components/parameters/generated_id'
        - $ref: '#/components/parameters/business_id'
          description: >-
            the business id of the TransportResource for which to add an
            unavailability
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransportResourceUnavailability'
      responses:
        '201':
          description: Unavailability updated.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportResourceUnavailability'
        '204':
          description: Unavailability updated.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - transport-resource-unavailability
      summary: '[EXPERIMENTAL] Delete TransportResource Unavailability by id'
      operationId: deleteTransportResourceUnavailability
      parameters:
        - $ref: '#/components/parameters/generated_id'
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: Unavailability deleted
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    get:
      tags:
        - transport-resource-unavailability
      summary: '[EXPERIMENTAL] Get TransportResource Unavailability by id'
      operationId: getTransportResourceUnavailability
      parameters:
        - $ref: '#/components/parameters/generated_id'
        - $ref: '#/components/parameters/business_id'
      responses:
        '200':
          description: Transport Resource Unavailability is retrieved
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportResourceUnavailability'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
  /means/{employee_id}/actual:
    get:
      operationId: getPagedEmployeeActuals
      tags:
        - actual
      summary: Get cursor-based actuals for an employee
      description: >
        Retrieve actuals for an employee in bulk using cursor-based paging (see
        the Cursor-based pagination documentation on the PTV Developer Portal).
      parameters:
        - name: employee_id
          in: path
          required: true
          description: |
            `employee_id` of the employee that the actuals applies to
          schema:
            type: string
          example: my-employee-id
        - in: query
          name: cursor
          schema:
            type: string
          required: false
          description: >
            The cursor of the page to return. No cursor is expected for the
            initial request. The cursors returned by this endpoint can be used
            for subsequent requests.
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          required: false
          description: |
            Number of results to return per page.
      responses:
        '200':
          description: >-
            The results for the current paged request and optional pointers to
            related result pages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPagedEmployeeActuals'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
  /means/{employee_id}/actual/{business_id}:
    put:
      tags:
        - actual
      summary: '[EXPERIMENTAL] Upsert Actual'
      operationId: upsertActual
      description: Upsert a single `Actual` for an `Employee`.
      parameters:
        - name: employee_id
          in: path
          required: true
          description: |
            `employee_id` of the employee that the Actual applies to
          schema:
            type: string
          example: my-employee-id
        - $ref: '#/components/parameters/business_id'
          description: >-
            Unique identifier for this `Actual`. Should only contain characters
            which do not need URL encoding.
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmployeeActual'
      responses:
        '201':
          description: Actual created or updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployeeActual'
        '204':
          description: Actual created or updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
            ETag:
              $ref: '#/components/headers/ETag'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
    get:
      tags:
        - actual
      summary: '[EXPERIMENTAL] Get Actual'
      operationId: getActual
      description: Get a single `Actual` for an `Employee`.
      parameters:
        - name: employee_id
          in: path
          required: true
          description: |
            `employee_id` of the employee that the Actual applies to
          schema:
            type: string
          example: my-employee-id
        - $ref: '#/components/parameters/business_id'
          description: >-
            Unique identifier for this `Actual`. Should only contain characters
            which do not need URL encoding.
      responses:
        '200':
          description: Actual retrieved
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmployeeActual'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - actual
      summary: '[EXPERIMENTAL] Delete Actual'
      operationId: deleteActual
      description: |
        Delete a single `Actual` for an `Employee`.
      parameters:
        - name: employee_id
          in: path
          required: true
          description: |
            `employee_id` of the employee that the Actual applies to
          schema:
            type: string
          example: my-employee-id
        - $ref: '#/components/parameters/business_id'
          description: >-
            Unique identifier for this `Actual`. Should only contain characters
            which do not need URL encoding.
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: Actual deleted
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '412':
          $ref: '#/components/responses/412'
  /resource-overview/{date}/{location}/forecasts:
    put:
      tags:
        - forecast
      summary: '[EXPERIMENTAL] Upsert Forecast'
      operationId: upsertForecast
      description: Upsert a single `Forecast`
      parameters:
        - name: date
          in: path
          required: true
          description: Date for which to upsert a forecast
          schema:
            type: string
            format: date
          example: '2023-10-01'
        - name: location
          in: path
          required: true
          description: Name of the location for which to upsert the forecast
          schema:
            type: string
          example: Ghent
        - $ref: '#/components/parameters/prefer'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Forecast'
      responses:
        '201':
          description: Forecast created or updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Forecast'
        '204':
          description: Forecast created or updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
    get:
      tags:
        - forecast
      summary: '[EXPERIMENTAL] Get Forecast'
      operationId: getForecast
      description: Get a single `Forecast`.
      parameters:
        - name: date
          in: path
          required: true
          description: Date for which to delete the forecast
          schema:
            type: string
            format: date
          example: '2023-10-01'
        - name: location
          in: path
          required: true
          description: Name of the location for which to delete the forecast
          schema:
            type: string
          example: Ghent
      responses:
        '200':
          description: Forecast retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Forecast'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - forecast
      summary: '[EXPERIMENTAL] Delete Forecast'
      operationId: deleteForecast
      description: Delete a single `Forecast`.
      parameters:
        - name: date
          in: path
          required: true
          description: Date for which to delete the forecast
          schema:
            type: string
            format: date
          example: '2023-10-01'
        - name: location
          in: path
          required: true
          description: Name of the location for which to delete the forecast
          schema:
            type: string
          example: Ghent
      responses:
        '204':
          description: Forecast deleted
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
  /home-base:
    get:
      operationId: getPagedHomeBases
      tags:
        - homebase
      summary: Get cursor-based home bases
      description: >
        Retrieve home bases in bulk using cursor-based paging (see the
        Cursor-based pagination documentation on the PTV Developer Portal).
      parameters:
        - in: query
          name: cursor
          schema:
            type: string
          required: false
          description: >
            The cursor of the page to return. No cursor is expected for the
            initial request. The cursors returned by this endpoint can be used
            for subsequent requests.
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          required: false
          description: |
            Number of results to return per page.
      responses:
        '200':
          description: >-
            The results for the current paged request and optional pointers to
            related result pages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPagedHomeBases'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
  /home-base/{business_id}:
    put:
      tags:
        - homebase
      summary: '[EXPERIMENTAL] Upsert Home Base'
      operationId: upsertHomeBase
      description: >
        Upsert a single `HomeBase`. Once it is created `Employees` and
        `Transport Resources` can make use of it.
      parameters:
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/prefer'
        - $ref: '#/components/parameters/if-match'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HomeBase'
      responses:
        '201':
          description: HomeBase created or updated
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HomeBase'
        '204':
          description: HomeBase created or updated
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '412':
          $ref: '#/components/responses/412'
    get:
      tags:
        - homebase
      summary: '[EXPERIMENTAL] Get Home Base'
      operationId: getHomeBase
      description: Get a single `HomeBase`.
      parameters:
        - $ref: '#/components/parameters/business_id'
      responses:
        '200':
          description: HomeBase retrieved
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HomeBase'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - homebase
      summary: '[EXPERIMENTAL] Delete Home Base'
      operationId: deleteHomeBase
      description: >
        Delete a single `HomeBase`.


        A `HomeBase` can only be deleted when there are no resources left
        referring to it.
      parameters:
        - $ref: '#/components/parameters/business_id'
        - $ref: '#/components/parameters/if-match'
      responses:
        '204':
          description: HomeBase deleted
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '409':
          $ref: '#/components/responses/409'
        '412':
          $ref: '#/components/responses/412'
  /deployment:
    get:
      operationId: getPagedDeployments
      tags:
        - deployment
      summary: '[EXPERIMENTAL] Get cursor-based deployments'
      description: >
        Retrieve deployments in bulk using cursor-based paging (see the
        Cursor-based pagination documentation on the PTV Developer Portal).

        `Deployments` without a `planning_id` are externally managed
        `Deployments`. 

        `Deployments` with a `planning_id` are managed by releasing or
        unreleasing routes in PTV OptiFlow.
      parameters:
        - in: query
          name: cursor
          schema:
            type: string
          required: false
          description: >
            The cursor of the page to return. No cursor is expected for the
            initial request. The cursors returned by this endpoint can be used
            for subsequent requests.
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          required: false
          description: |
            Number of results to return per page.
      responses:
        '200':
          description: >-
            The results for the current paged request and optional pointers to
            related result pages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPagedDeployments'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
  /deployment/{id}:
    get:
      tags:
        - deployment
      operationId: getDeployment
      summary: '[EXPERIMENTAL] Get Deployment'
      description: >
        Get an existing `Deployment`, defined by their `id`. `Deployments`
        without a `planning_id` are externally managed `Deployments`. 

        `Deployments` with a `planning_id` are managed by releasing or
        unreleasing routes in PTV OptiFlow.
      parameters:
        - name: id
          in: path
          required: true
          description: |
            The unique ID used to identify this `Deployment`.
          schema:
            type: string
      responses:
        '200':
          description: >
            The `Deployment` was successfully retrieved. Details are in the
            response body.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    put:
      tags:
        - deployment
      summary: '[EXPERIMENTAL] Upsert External Deployment'
      operationId: upsertExternalDeployment
      description: >
        Create or update an external `Deployment`. A unique ID (`id`) is
        required to identify the `Deployment`. 

        Calling this endpoint with an existing `id` will update the
        `Deployment`.


        External `Deployments` represent work assignments that are managed
        outside of the Resource Management system.


        We don't allow overlap between `Deployments` for the same `Employee` or
        `Transport Resource`.
      parameters:
        - name: id
          in: path
          required: true
          description: >-
            Unique identifier for this external `Deployment`. Should only
            contain characters which do not need URL encoding.
          schema:
            type: string
        - $ref: '#/components/parameters/prefer'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalDeployment'
      responses:
        '201':
          description: External Deployment created or updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
        '204':
          description: External Deployment created or updated
          headers:
            Preference-Applied:
              $ref: '#/components/headers/Preference-Applied'
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    delete:
      tags:
        - deployment
      operationId: deleteExternalDeployment
      summary: '[EXPERIMENTAL] Delete External Deployment'
      description: >
        Delete an external `Deployment`, defined by their `id`. It is not
        possible to delete `Deployments` that are managed by the PTV OptiFlow
        platform. 

        In order to remove these `Deployments`, you can use the `planning_id` to
        unrelease the corresponding route in the PTV OptiFlow planning.
      parameters:
        - name: id
          in: path
          required: true
          description: Unique identifier for this external `Deployment`.
          schema:
            type: string
      responses:
        '204':
          description: |
            Deletion has succeeded and body is empty.
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
components:
  parameters:
    business_id:
      name: business_id
      in: path
      description: >-
        A unique identifier of an entity instance. Should only contain
        characters which do not need URL encoding.
      required: true
      schema:
        type: string
        pattern: ^[a-zA-Z0-9.~\-_]{1,512}$
    generated_id:
      name: generated_id
      in: path
      description: A generated identifier for an entity instance.
      required: true
      schema:
        type: string
        format: uuid
    prefer:
      name: Prefer
      in: header
      description: |
        The RFC7240 Prefer header indicates that a particular server behavior
        is preferred by the client but is not required for successful completion
        of the request (see [RFC 7240](https://tools.ietf.org/html/rfc7240)).

        The following behavior (see _Examples_) is supported by this API:
        * **return=<minimal|representation>** is used to suggest the server to
          return using 204 without resource (minimal) or using 200 or 201 with
          resource (representation) in the response body on success.
      schema:
        type: array
        items:
          type: string
      examples:
        minimal:
          value:
            - return=minimal
          description: Indicate no response is needed, can be omitted
        representation:
          value:
            - return=representation
          description: Request the result of the operation as response
    if-match:
      name: If-Match
      in: header
      description: Weak Etag used for optimistic locking.
      schema:
        type: string
        example: W/"24"
  schemas:
    CursorPagedEmployees:
      type: object
      properties:
        data:
          type: array
          description: |
            The set of results for the current page.
          items:
            allOf:
              - $ref: '#/components/schemas/Employee'
              - type: object
                properties:
                  etag:
                    type: string
                    example: W/"25"
        cursors:
          $ref: '#/components/schemas/Cursors'
    Cursors:
      type: object
      description: >
        The cursors represent pointers to pages of results in relation to the
        page that was retrieved by the current request. These pointers are
        nullable. For more information

        on these pointers, view the Developer Portal.
      properties:
        previous:
          type: string
          description: Pointer to the previous page of results.
        self:
          type: string
          description: >-
            Pointer to the current page of results. When changing the limit in
            subsequent requests, the first 'limit' results will be contained in
            the page.
        next:
          type: string
          description: Pointer to the next page of results.
    Employee:
      type: object
      properties:
        business_id:
          type: string
          pattern: ^[a-zA-Z0-9.~\-_]+$
          readOnly: true
          example: employee-42
          description: |
            Unique identifier for this `Employee`.
        name:
          $ref: '#/components/schemas/EmployeeName'
        driver_skills:
          type: array
          description: >
            `driver_skills` are only meaningful in relation to a linked
            `TransportResource`. They are skills of the `Employee` that
            determine the feasibility of

            a `ResourceCombination` and the resulting capabilities of this
            `ResourceCombination`.
          items:
            type: string
          example:
            - digital side mirrors
            - driving license D
        skills:
          type: array
          description: >
            `skills` are inherent to the `Employee` regardless of the vehicle
            they are operating, such as language skills. They are available to
            the `ResourceCombination`, 

            regardless of the linked `TransportResource`.
          items:
            type: string
          example:
            - Dutch
            - English
        start_location:
          $ref: '#/components/schemas/NamedGeoAddress'
          description: >
            An ad-hoc location from which this `Employee` will start each work
            shift, unless otherwise specified on more specific entities. When
            using an ad-hoc 

            location, the `Employee` will only be assigned to
            `TransportResources` with a matching `start_location` (name-based
            match).


            Either address information or geo point must be provided. Resolved
            address information will be read only and be filled out after
            resolving. 


            Either a `home_base` or a `start_location` must be provided.
        home_base:
          $ref: '#/components/schemas/LinkedHomeBase'
          description: >
            The `business_id` of a known `HomeBase` in the system. This
            represents the location from which this `Employee` will start each
            work shift, unless otherwise 

            specified on more specific entities. When located at a `HomeBase`,
            the `Employee` will only be assigned to `TransportResources` with a
            matching `home_base`. 

            This is conceptually the same as using an ad-hoc `start_location`,
            but with centralized address management which automatically
            propagates changes on the 

            root entity.


            Either a `home_base` or a `start_location` must be provided.
        linked_resource:
          type: string
          description: >
            A reference to the `TransportResource` (by `business_id`) which
            should be linked to this `Employee` if possible. The algorithm will
            try to adhere to 

            this requirement as much as possible, but this may not be possible
            in case of:  

            * differing `start_location`/`home_base`

            * conflicting `linked_resource` on another `Employee` with
            overlapping availabilities

            * unavailability of the `TransportResource`.
          example: 0-ABC-123
        wont_do:
          type: array
          items:
            type: string
          description: >
            Allows you to control the capabilities of a `ResourceCombination`
            for this `Employee`. This property can be used to disable a
            `TransportResource`'s 

            capabilities.


            A use case could be disabling one type of cargo due. Suppose the
            `Employee` is unable to handle the _big bag_ cargo type, but you
            chose to define cargo 

            types as `capabilities` on the `TransportResource`, you can add _big
            bag_ to this `Employee`'s won't do.
          example:
            - big bag
        cost:
          description: >
            Costs associated with this `Employee`, which will be combined with
            assigned `TransportResources` in the resulting
            `ResourceCombination`. These costs

            help steer the optimization algorithm towards an optimal solution.


            The addition of costs maintains a precision of 4.
          $ref: '#/components/schemas/Cost'
        labels:
          type: array
          items:
            type: string
          description: >
            Labels provided by the `Employee` to its `ResourceCombination`.
            Using `labels` allows you to select subsets of
            `ResourceCombinations` for use in an 

            optimization by configuring them in the _Resource Filter_.
          example:
            - Employee-label-A
        route_settings:
          type: object
          description: >
            [EXPERIMENTAL] Various properties that will have an impact on the
            planning of a route in PTV OptiFlow.
          properties:
            driving_speed_factor:
              type: number
              format: double
              description: >
                [EXPERIMENTAL] This is the factor by which the default speed of
                the resulting `ResourceCombination` gets multiplied.


                A use case could be a learning driver that might drive 10%
                slower than his/her colleagues. Setting the
                `driving_speed_factor` to 0.90 ensures the optimization
                algorithm takes this into account.
              example: 1.25
              exclusiveMinimum: 0
            max_stops_per_shift:
              type: integer
              description: >
                [EXPERIMENTAL] This will affect the maximum number of stops an
                `Employee` will get planned for in PTV OptiFlow.


                Use this property to ensure that drivers don't get assigned too
                many stops.
              example: 3
              minimum: 1
              maximum: 1000000
        custom_data:
          $ref: '#/components/schemas/CustomData'
      required:
        - business_id
    EmployeeName:
      type: object
      description: >
        The name of this `Employee`. Both properties are nullable to allow for
        regional differences.
      properties:
        first_name:
          type: string
          example: Jan
          description: |
            The given name of this `Employee`.
        last_name:
          type: string
          example: Van den Berghe
          description: |
            The surname of this `Employee`.
    EmployeeUnavailability:
      type: object
      description: A single `Unavailability` for an `Employee`.
      properties:
        id:
          description: The unique `Unavailability` ID.
          type: string
          example: f22896d0-ed42-4a14-a935-7a29072bc5ac
          readOnly: true
        employee_id:
          $ref: '#/components/schemas/EmployeeId'
        from:
          type: string
          format: date-time
          example: '2021-01-01T06:00:00Z'
        to:
          type: string
          format: date-time
          example: '2021-01-10T06:00:00Z'
        description:
          type: string
          example: holiday
      required:
        - from
        - to
    EmployeeUnavailabilities:
      type: array
      items:
        allOf:
          - $ref: '#/components/schemas/EmployeeUnavailability'
          - type: object
            properties:
              version:
                $ref: '#/components/schemas/Version'
    Cost:
      type: object
      properties:
        per_kilometer:
          description: >
            A cost to be applied per kilometer in the optimization when
            utilizing this resource.
          type: number
          format: double
          example: 0.9
          default: 0
          minimum: 0
        per_hour:
          description: >
            An hourly cost to be applied in the optimization when utilizing this
            resource.
          type: number
          format: double
          example: 46.8
          default: 0
          minimum: 0
        fixed:
          description: >
            The fixed cost to be applied in the optimization when utilizing this
            resource.
          type: number
          format: double
          example: 213
          default: 0
          minimum: 0
    Characteristics:
      type: object
      description: |
        [EXPERIMENTAL]
        Technical characteristics of this `TransportResource`.
      properties:
        maximum_allowed_weight:
          description: |
            The maximum allowed weight for this cargo unit.
            This cannot be provided for transport resources of type `TRACTOR`.
          type: number
          format: double
          example: 3500
          minimum: 0
    RouteSettings:
      type: object
      description: |
        Route settings for this `TransportResource`.
      properties:
        direct_trips:
          description: |
            Restricts this `TransportResource` to direct trips during planning.
          type: boolean
          example: false
      required:
        - direct_trips
    CursorPagedEmployeeActuals:
      type: object
      properties:
        data:
          type: array
          description: |
            The set of results for the current page.
          items:
            allOf:
              - $ref: '#/components/schemas/EmployeeActual'
              - type: object
                properties:
                  etag:
                    type: string
                    example: W/"25"
        cursors:
          $ref: '#/components/schemas/Cursors'
    EmployeeActual:
      allOf:
        - type: object
          properties:
            employee_id:
              type: string
              example: hvertenten
              readOnly: true
          required:
            - employee_id
        - $ref: '#/components/schemas/BaseEmployeeActual'
    BaseEmployeeActual:
      type: object
      description: >
        [EXPERIMENTAL]

        Actual work time a certain employee has executed for a particular date
        and time.
      properties:
        business_id:
          type: string
          pattern: ^[a-zA-Z0-9.~\-_]+$
          readOnly: true
          example: 14-05-2025-morning-shift
          description: |
            Unique identifier for this `Actual`.
        start:
          description: |
            A date and time when the activity was started.
          type: string
          format: date-time
          example: '2025-05-14T08:00:00Z'
        end:
          description: |
            A date and time when the activity has ended.
          type: string
          format: date-time
          example: '2025-05-14T17:00:00Z'
        work_time:
          description: >
            The total work time performed by an `Employee`. Must be an ISO-8601
            compliant Duration string. Must be strictly positive.
          type: string
          format: ISO-8601
          example: PT8H
      required:
        - business_id
        - start
        - work_time
    Availabilities:
      type: array
      uniqueItems: true
      items:
        allOf:
          - $ref: '#/components/schemas/Availability'
          - type: object
            properties:
              version:
                $ref: '#/components/schemas/Version'
    Availability:
      type: object
      description: >
        An `Availability` for an `Employee` that describes the interval in which
        the employee is available to work. The `Availability` is the basis for
        creating

        a `ResourceCombination` (combining the `Employee` with
        `TransportResources`) but can be altered by the presence of (partially)
        overlapping `Unavailabilities`

        or `Relocations` (only managed through the user interface).
      properties:
        id:
          description: The unique `Availability` ID.
          type: string
          readOnly: true
          example: f22896d0-ed42-4a14-a935-7a29072bc5ac
        employee_id:
          $ref: '#/components/schemas/EmployeeId'
        start_location:
          $ref: '#/components/schemas/AvailabilityStartLocation'
          description: >
            An ad-hoc location from which this `Employee` will start this
            specific work shift. This overrides the ad-hoc `start_location` or
            home base on the 

            `Employee`. When using an ad-hoc location, the `Employee` will only
            be assigned to `TransportResources` with a matching `start_location`
            (name-based 

            match), unless that employee is on a `Journey`. In that case they
            will continue to use the same `TransportResource` until the
            `Journey` is done.


            Either address information or geo point must be provided. Resolved
            address information will be read-only and be filled out after
            resolving. 
        home_base_id:
          description: >
            The `business_id` of a known `HomeBase` in the system. This
            represents the location from which this `Employee` will start this
            specific work shift. This 

            overrides the  ad-hoc `start_location` or home base on the
            `Employee`.  When located at a `Home`Base, the `Employee` will only
            be assigned to Transport`Resources` 

            with a matching `home_base`. This is conceptually the same as using
            an ad-hoc `start_location`, but with centralized address management
            which automatically 

            propagates changes on the root `HomeBase` entity.


            A `home_base` is mutually exclusive with providing an ad-hoc
            `start_location`, but neither is mandatory for an `Availability`.


            Deprecated in favor of the `start_location` property.
          type: string
          example: a-home-base-id
          deprecated: true
        end_location:
          $ref: '#/components/schemas/EndLocation'
        earliest_start:
          type: string
          format: date-time
          example: '2021-01-01T04:15:30Z'
          description: |
            The earliest instant that the `Employee` can start this work shift.
        latest_start:
          type: string
          format: date-time
          example: '2021-01-01T06:00:00Z'
          description: >
            The latest instant that the `Employee` can start this work shift. If
            not provided, the optimization will potentially introduce wait time
            starting from

            the `earliest_start` if this `Employee` is used to execute tasks.
        latest_stop:
          description: >
            The latest time at which the availability should end. This can be
            useful for defining schedules with a lenient start window, but where
            the Employee 

            has a hard stop at a certain time. It should be between
            (`earliest_start + min_duration`) and (`latest_start +
            max_duration`).


            If no `latest_stop` is provided, it will be extrapolated from the
            `latest_start` and `max_duration` properties.
          type: string
          format: date-time
          example: '2021-01-01T16:00:00Z'
        min_duration:
          description: >
            The minimal duration of a shift during the `Availability`. Must be
            an ISO-8601 compliant Duration string. If no `min_duration` is
            provided, the application

            will treat the `max_duration` as the `min_duration` when it needs to
            determine the timeframe in which this shift ends.
          type: string
          example: PT8H
        max_duration:
          description: >
            The maximum duration of a shift during the `Availability`. Must be
            an ISO-8601 compliant Duration string.
          type: string
          example: PT12H
        mandatory:
          description: >-
            Indicates whether the resulting combination is required to be used
            when planned
          type: boolean
          default: false
          example: true
      required:
        - earliest_start
        - max_duration
    ShiftSchedules:
      type: array
      items:
        allOf:
          - $ref: '#/components/schemas/ShiftSchedule'
          - type: object
            properties:
              version:
                $ref: '#/components/schemas/Version'
                description: >-
                  The version of the shift schedule. Present when the shift
                  schedule is returned in a list in a response.
    ShiftSchedule:
      type: object
      description: The Shift Schedule for an `Employee`
      properties:
        id:
          description: >
            The unique `ShiftSchedule` ID, generated by the application upon
            creation.
          type: string
          example: f22896d0-ed42-4a14-a935-7a29072bc5ac
          readOnly: true
        name:
          description: |
            An optional name for this `ShiftSchedule`.
          type: string
          example: Standard 38H
        start:
          $ref: '#/components/schemas/ShiftScheduleStart'
        templates:
          type: array
          minLength: 1
          description: >
            List of non-null objects describing one calendar week (MON-SUN)
            worth of shifts.
          items:
            $ref: '#/components/schemas/RecurrencePeriod'
      required:
        - templates
        - start
    EmployeeId:
      type: string
      description: The unique `Employee` ID.
      pattern: ^[a-zA-Z0-9.~\-_]+$
      readOnly: true
      example: employee-42
    RecurrencePeriod:
      type: object
      description: |
        Shifts within one calendar week.
      properties:
        index:
          type: integer
          minimum: 1
          description: >
            One-based index that determines the order in the schedule. Indices
            should be consecutive within a `ShiftSchedule`, without gaps.
            Setting up a schedule

            with a recurring week off can be achieved by providing an empty
            `shift`-array within the corresponding week's template.
        shifts:
          type: array
          description: >
            List of non-null shifts in this calendar week. The list can remain
            empty to represent a recurring week off. 


            Shifts should not overlap within one template, but can also not
            overlap with the adjoining shift of other templates. The last shift
            within a template 

            will be validated against the first shift of the next template. When
            this template is the last template of the schedule the application
            will roll over 

            to the first template of the schedule for validating the
            non-overlapping constraint. This also means a single-week schedule
            should not have any overlap

            between the last and first shift of the schedule.
          items:
            $ref: '#/components/schemas/Shift'
        acceptable_additional_work_time:
          type: string
          description: >
            The additional time an employee is willing to work, if needed,
            beyond their contractual hours during the current calendar week.

            This value is used to determine whether the employee’s actual work
            time exceeds what they are willing to work — defined as the sum of
            their

            contractual work time and this additional work time.


            If this field is provided, contractual_work_time must also be
            specified for each shift in the calendar week.


            The value must be a strictly positive ISO 8601-compliant duration.

            [EXPERIMENTAL]
          example: PT4H
      required:
        - index
        - shifts
    Shift:
      type: object
      properties:
        start:
          type: object
          description: |
            The start range for this specific shift.
          properties:
            earliest:
              $ref: '#/components/schemas/TimeInWeek'
            window:
              description: >
                Duration from the `earliest` start until the latest start,
                formatted as an ISO-8601 compliant Duration string. If provided,
                it must be positive.
              type: string
              example: PT3H
          required:
            - earliest
        stop:
          type: object
          description: |
            Optional constraints on when this shift should finish.
          properties:
            latest:
              $ref: '#/components/schemas/TimeInWeek'
              description: >
                An (optional) latest stop. This can be useful for defining
                schedules with a lenient start window, but where the `Employee`
                has a hard stop at a certain

                time.


                The latest stop must be within the (calculated) bounds of this
                `Shift`'s end. These bounds are defined as follows:

                * earliest stop:   
                  If `duration.at_least` is:  
                  * provided: `start.earliest + duration.at_least`
                  * not provided: `start.earliest + duration.at_most`
                * latest stop:  
                  `start.earliest + (optional) start.window + duration.at_most`
        duration:
          type: object
          description: The limits of the duration of this shift.
          properties:
            at_least:
              description: >
                The minimal duration of a shift. Must be an ISO-8601 compliant
                Duration string. If provided, it must be strictly positive and
                greater than or equal 

                to `start.window`.
              type: string
              example: PT8H
            at_most:
              description: >
                The maximum duration of a shift. Must be an ISO-8601 compliant
                Duration string.  


                Must be:

                * strictly positive, 

                * greater than or equal to `start.window` 

                * greater than or equal to `at_least` if it is provided.

                * lower than `P7D` (7 days).
              type: string
              example: PT12H
          required:
            - at_most
        mandatory:
          description: >-
            Indicates whether the resulting combination is required to be used
            when planned.
          default: false
          type: boolean
          example: true
        start_location:
          $ref: '#/components/schemas/ShiftStartLocation'
          description: >
            By default, each `Shift` will start on the `start_location` defined
            on the `Employee`. By specifying this `start_location`, this
            `Employee` will start this `Shift` on this `start_location`.


            Either a `home_base` or a `address` must be provided.
        end_location:
          $ref: '#/components/schemas/EndLocation'
        contractual_work_time:
          type: string
          description: >
            The duration an employee is contractually expected to work during
            this shift.

            This value is used to determine whether the employee worked more or
            less than expected based on their contract.

            Note that only the at_least and at_most durations for the current
            shift influence the work time that will be planned for this shift.


            If this field is provided, it must be specified for each shift
            within the shift schedule.

            Additionally, acceptable_additional_work_time must be defined for
            each calender week.


            The value must be a zero or positive ISO 8601-compliant duration.

            [EXPERIMENTAL]
          example: PT8H
      required:
        - start
        - duration
    AvailabilityStartLocation:
      type: object
      properties:
        address:
          $ref: '#/components/schemas/NamedGeoAddress'
          description: >
            An ad-hoc location from which this `Employee` will start this
            specific work `Availability`. This overrides the  ad-hoc
            `start_location` or home base on the 

            `Employee`. When using an ad-hoc location, the `Employee` will only
            be assigned to `TransportResources` with a matching `start_location`
            (name-based 

            match).


            Either address information or geo point must be provided. Resolved
            address information will be read only and be filled out after
            resolving. 


            An ad-hoc `start_location` is mutually exclusive with providing a
            `home_base` or setting `at_last_end`, but neither are mandatory for
            an `Availability`.
        home_base:
          $ref: '#/components/schemas/LinkedHomeBase'
          description: >
            The `business_id` of a known `HomeBase` in the system. This
            represents the location from which this `Employee` will start this
            `Availability`, unless otherwise specified on more specific
            entities. When located at a `HomeBase`, the `Employee` will only be
            assigned to `TransportResources` with a matching `home_base`. 

            This is conceptually the same as using an ad-hoc `address` but with
            centralized address management which automatically propagates
            changes on the 

            root entity.


            A `home_base` is mutually exclusive with providing an `address` or
            setting `at_last_end`, but neither are mandatory for an
            `Availability`.
        at_last_end:
          type: boolean
          default: false
          description: >
            When this is set, the planning will use the end location of the
            preceding deployed `ResourceCombination` as the starting point for
            this one.


            This is mutually exclusive with providing an `address` or a
            `home_base`, but neither are mandatory for an `Availability`.
        name:
          type: string
          description: >
            A name by which to identify this location. If used as a
            `start_location`, this is used for matching coloecated entities.

            Deprecated in favor of the `address` field.

            This is required only when using the deprecated fields.
          example: Conundra
          deprecated: true
        address_line:
          type: string
          example: Voordries 41b
          description: >
            The address line of this location's address. Can contain street,
            house number, bus and more.

            Deprecated in favor of the `address` field.
          deprecated: true
        city:
          type: string
          example: Oosterzele
          description: |
            The name of the locality of this location.
            Required when no `geo_point` is provided.
            Deprecated in favor of the `address` field.
          deprecated: true
        zip_code:
          type: string
          example: '9860'
          description: |
            The ZIP code of the locality of this location.
            Required when no `geo_point` is provided.
            Deprecated in favor of the `address` field.
          deprecated: true
        country_code:
          $ref: '#/components/schemas/CountryCode'
          description: |
            The ISO3166-1 alpha-2 two letter country code for this location.
            Required when no `geo_point` is provided.
            Deprecated in favor of the `address` field.
          deprecated: true
        geo_point:
          $ref: '#/components/schemas/GeoPoint'
          deprecated: true
          description: |
            Deprecated in favor of the `address` field.
    ShiftStartLocation:
      type: object
      properties:
        address:
          $ref: '#/components/schemas/NamedGeoAddress'
          description: >
            An ad-hoc location from which this `Employee` will start this
            specific work `Shift`. This overrides the  ad-hoc `start_location`
            or home base on the 

            `Employee`. When using an ad-hoc location, the `Employee` will only
            be assigned to `TransportResources` with a matching `start_location`
            (name-based 

            match).


            Either address information or geo point must be provided. Resolved
            address information will be read only and be filled out after
            resolving. 


            An ad-hoc `start_location` is mutually exclusive with providing a
            `home_base` or setting `at_last_end`, but neither are mandatory for
            a `Shift`.
        home_base:
          $ref: '#/components/schemas/LinkedHomeBase'
          description: >
            The `business_id` of a known `HomeBase` in the system. This
            represents the location from which this `Employee` will start this
            `Shift`, unless otherwise specified on more specific entities. When
            located at a `HomeBase`, the `Employee` will only be assigned to
            `TransportResources` with a matching `home_base`. 

            This is conceptually the same as using an ad-hoc `address` but with
            centralized address management which automatically propagates
            changes on the 

            root entity.


            A `home_base` is mutually exclusive with providing an `address` or
            setting `at_last_end`, but neither are mandatory for an `Shift`.
        at_last_end:
          type: boolean
          default: false
          description: >
            When this is set to true, the planning will use the end location of
            the preceding deployed `ResourceCombination` as the starting point
            for this shift.


            This is mutually exclusive with providing an `address` or a
            `home_base`, but neither are mandatory for an `Shift`.
    ShiftScheduleStart:
      type: object
      description: The start date and start week number of this shift schedule
      properties:
        start_date:
          type: string
          format: date
          description: The calendar day at which this schedule starts.
          example: '2014-08-16'
        start_week:
          type: integer
          description: >
            The one-based index of the template at which this schedule starts.
            This allows you to offset the week from which the application start
            extrapolating

            the potential availability of an `Employee`. This can be useful for
            instances where an `Employee` has a multi-week schedule but you want
            the even and uneven weeks to line up with the weeks of the

            year.


            The index should always be within the bounds of the schedule's
            template indices.
          minimum: 1
          example: 1
      required:
        - start_date
        - start_week
    TimeInWeek:
      description: |
        Specifies a time on a specified day of the week.
      type: object
      properties:
        time:
          $ref: '#/components/schemas/Time'
        day:
          $ref: '#/components/schemas/DayOfWeek'
      required:
        - time
        - day
    Time:
      description: |
        Specify a time, formatted as `hh:mm`. Supports 00:00-23:59 inclusive.
      type: string
      pattern: ^([0-1][0-9]|[2][0-3]):([0-5][0-9])$
      example: '14:45'
    DayOfWeek:
      type: string
      example: MONDAY
      description: |
        Specifies a day of the week, must match the exhaustive set of values.
      enum:
        - MONDAY
        - TUESDAY
        - WEDNESDAY
        - THURSDAY
        - FRIDAY
        - SATURDAY
        - SUNDAY
    CustomData:
      title: CustomData
      description: >
        Custom data is an extendable hashmap of key-value pairs for client
        usage. These values have no meaning in the context of Resource
        Management, but can be used to 

        enrich the data in OptiFlow with relevant information for the end
        users.    


        Keys should not be blank nor contain periods.
      additionalProperties:
        type: string
        description: >
          A single key-value pair, with the value being an optional string.


          The platform distinguishes between `null` values (there is no value
          for this key) and empty values (the value of this key is an empty
          string: `""`).

          When setting the value of a custom data property to an empty string,
          the key will still be present on a vehicle in an OptiFlow Match
          planning (for relevant

          entities), whereas setting the value to `null` signifies that this key
          is not a part of this entity.
      example:
        shop_manager: John Smith
    GeoPoint:
      properties:
        latitude:
          type: number
          format: double
          example: 50.9514048
        longitude:
          type: number
          format: double
          example: 3.8067878
        resolved:
          readOnly: true
          type: object
          description: Indicates whether the address is resolved.
          properties:
            geocoded:
              type: boolean
              example: true
            address:
              type: string
              example: Voordries 31 bus B, 9860 Oosterzele
            precision:
              type: integer
              example: 9
      required:
        - latitude
        - longitude
    GeoAddress:
      type: object
      description: >-
        Either address information should be present, or otherwise the geo
        point. The resolved information will be read only and be filled out
        after resolving.
      properties:
        address_line:
          type: string
          example: Voordries 41b
          description: >
            The address line of this location's address. Can contain street,
            house number, bus and more.
        city:
          type: string
          example: Oosterzele
          description: |
            The name of the locality of this location.

            Required when no `geo_point` is provided.
        zip_code:
          type: string
          example: '9860'
          description: |
            The ZIP code of the locality of this location.

            Required when no `geo_point` is provided.
        country_code:
          $ref: '#/components/schemas/CountryCode'
          description: |
            The ISO3166-1 alpha-2 two letter country code for this location.

            Required when no `geo_point` is provided.
        geo_point:
          $ref: '#/components/schemas/GeoPoint'
    EndLocation:
      type: object
      description: >
        [EXPERIMENTAL] Property to define an `endLocation`. When left blank, the
        `Employee` will make a round-trip and the `endLocation` will match the
        `startLocation`.


        Only one option is allowed, either `address`, `home_base` or
        `at_last_activity` can be set.
      properties:
        address:
          $ref: '#/components/schemas/NamedGeoAddress'
          description: >
            An ad-hoc address where this `Employee` will end during this
            specific `Availability`. 


            Either address information or geo point must be provided. Resolved
            address information will be read-only and be filled out after
            resolving.
        home_base:
          $ref: '#/components/schemas/LinkedHomeBase'
          description: >
            The `business_id` of a know `HomeBase` where this `Employee` will
            end during this specific `Availability`.
        at_last_activity:
          type: boolean
          description: >
            The optimization will determine the best (eg: most cost-effective)
            location. This location will always be an `Order`'s location. This
            option can only 

            be honored for plannings that do a PickupDelivery optimization. When
            set for other types of plannings, the optimization will result in a
            round trip.
    NamedGeoAddress:
      type: object
      description: >-
        Either textual address information or geo point must be provided. The
        resolved information will be read only and be filled out after
        resolving.
      allOf:
        - type: object
          properties:
            name:
              type: string
              description: >
                A name by which to identify this location. If used as a
                `start_location`, this is used for matching colocated entities.
              example: Conundra
        - $ref: '#/components/schemas/GeoAddress'
      required:
        - name
    LinkedHomeBase:
      type: object
      description: >
        Conceptually the same as `start_location`, but with centralized address
        management.


        Either a `home_base` or a `start_location` must be provided.
      properties:
        business_id:
          description: |
            The unique identifier of a `HomeBase`.
          type: string
          example: depot-1
      required:
        - business_id
    Capacity:
      title: Capacity
      type: object
      description: |
        Dimensional value of a capacity.
      properties:
        type:
          type: string
          enum:
            - volume
            - weight
            - loadingMeters
            - capacity1
            - capacity2
            - capacity3
            - capacity4
            - capacity5
          description: characterization of a capacity, default volume
          default: volume
        value:
          type: number
          format: double
          example: 20.02
      required:
        - value
    CountryCode:
      description: represents the ISO3166-1 alpha-2 two letter country codes
      type: string
      pattern: ^[A-Z]{2}$
      example: BE
    Forecast:
      description: The expected number of shifts for a given date and location
      type: object
      properties:
        expected_shifts:
          type: integer
          minimum: 0
          description: Expected number of shifts
          example: 27
        location:
          readOnly: true
          type: string
          description: Name of the location
          example: Ghent
        date:
          readOnly: true
          description: Date of the forecast
          type: string
          format: date
          example: '2023-10-01'
    CursorPagedHomeBases:
      type: object
      properties:
        data:
          type: array
          description: |
            The set of results for the current page.
          items:
            allOf:
              - $ref: '#/components/schemas/HomeBase'
              - type: object
                properties:
                  etag:
                    type: string
                    example: W/"25"
        cursors:
          $ref: '#/components/schemas/Cursors'
    HomeBase:
      description: >-
        The location where an employee or transport resource is usually found.
        Combinations will only be made with resources within the same home base.
      type: object
      properties:
        business_id:
          type: string
          pattern: ^[a-zA-Z0-9.~\-_]+$
          example: HB-GHENT-01
          readOnly: true
        name:
          type: string
          description: Name of the home base
          example: Ghent - Headquarters
        address:
          $ref: '#/components/schemas/GeoAddress'
        plan_group:
          type: string
          description: the plan group to which this `HomeBase` belongs
          example: cargo planning
    CursorPagedTransportResources:
      type: object
      properties:
        data:
          type: array
          description: |
            The set of results for the current page.
          items:
            allOf:
              - $ref: '#/components/schemas/TransportResource'
              - type: object
                properties:
                  etag:
                    type: string
                    example: W/"25"
        cursors:
          $ref: '#/components/schemas/Cursors'
    TransportResource:
      type: object
      properties:
        business_id:
          type: string
          pattern: ^[a-zA-Z0-9.~\-_]+$
          readOnly: true
          example: tractor-1
        type:
          $ref: '#/components/schemas/ResourceType'
        license_plate:
          type: string
          example: 1-ABC-987
        requirements:
          type: array
          uniqueItems: true
          description: >-
            List of requirements the `Employee` must fulfill to be allowed to
            use this `TransportResource`.
          items:
            type: string
            example: driving license CE
        capabilities:
          type: array
          uniqueItems: true
          description: >-
            Capabilities this `TransportResource` provides to the
            `ResourceCombination`.
          items:
            type: string
            example: big bag
        required_capabilities:
          type: array
          uniqueItems: true
          description: >-
            List of requirements the `Employee` must fulfill, which will be
            provided as capabilities to the `ResourceCombination`.
          items:
            type: string
            example: cooling compressor
        skilled_capabilities:
          type: array
          uniqueItems: true
          description: >-
            List of capabilities which will be provided to the
            `ResourceCombination`, if the `Employee` has matching
            `driver_skills`.
          items:
            type: string
            example: sideloading
        cant_do:
          type: array
          uniqueItems: true
          description: >
            List of capabilities which will be disabled on the resulting
            `ResourceCombination`.

            For example: A TRACTOR with a faulty electric plug, can not be used
            with a TRAILER that exposes a capability which requires this plug.
          items:
            type: string
            example: adr-transport
        capacities:
          type: array
          description: |
            These capacities mirror the `Order Book` capacities.
          minItems: 1
          maxItems: 8
          uniqueItems: true
          items:
            $ref: '#/components/schemas/Capacity'
        linked_resource:
          type: string
          description: >
            The `business_id` of another `TransportResource` on the same
            location that should be coupled with this one no matter what.

            This is known as a fixed coupling.


            By using this you can indicate that a tractor should always be
            coupled with a specific trailer (or the other way around).

            There is no need to specify the linking in both directions.

            This overwrites all requirements and as such could lead to seemingly
            invalid situations, but this is at the discretion of the planner.
          example: trailer-1
        start_location:
          $ref: '#/components/schemas/NamedGeoAddress'
          description: >
            The `start_location` where this `TransportResource` is based.


            Either address information or geo point must be provided. The
            resolved information will be read only and be filled out after
            resolving. 


            Either a `home_base` or a `start_location` must be provided.
        home_base:
          $ref: '#/components/schemas/LinkedHomeBase'
          description: >
            Conceptually the same as `start_location`, but with centralized
            address management.


            Either a `home_base` or a `start_location` must be provided.
        reference:
          description: >
            Optional, internal reference (eg: fleet number, ...) for the
            `TransportResource`.
          type: string
          example: fleet-reference-47
        custom_data:
          $ref: '#/components/schemas/CustomData'
        labels:
          type: array
          items:
            type: string
          description: Labels provided by the `TransportResource` for its `Combination`.
          example:
            - Transport-resource-label-A
        inactive:
          type: boolean
          default: false
          description: >-
            Flag to indicate whether a `TransportResource` can be used for
            creating `ResourceCombinations`. When set to `true`, all future
            `ResourceCombinations` will be removed.
        cost:
          $ref: '#/components/schemas/Cost'
        characteristics:
          $ref: '#/components/schemas/Characteristics'
        route_settings:
          $ref: '#/components/schemas/RouteSettings'
      required:
        - business_id
        - type
    TransportResourceId:
      type: string
      description: The business id of a `TransportResource`.
      pattern: ^[a-zA-Z0-9.~\-_]+$
      readOnly: true
      example: tractor-1
    TransportResourceUnavailabilities:
      type: array
      items:
        allOf:
          - $ref: '#/components/schemas/TransportResourceUnavailability'
          - type: object
            properties:
              version:
                $ref: '#/components/schemas/Version'
    TransportResourceUnavailability:
      type: object
      description: A single `Unavailability` for a `TransportResource`.
      properties:
        id:
          description: The unique `Unavailability` ID.
          type: string
          readOnly: true
        transport_resource_id:
          description: The `TransportResource` that has this `Unavailability`.
          $ref: '#/components/schemas/TransportResourceId'
        from:
          type: string
          format: date-time
          example: '2021-01-01T06:00:00Z'
        to:
          description: must be strictly greater than `from`
          type: string
          format: date-time
          example: '2021-01-10T06:00:00Z'
        description:
          type: string
          example: maintenance
      required:
        - from
        - to
    ResourceType:
      description: >
        A `TRACTOR` is a pulling  unit, a `TRAILER` a cargo unit and a `TRUCK`
        is both a pulling and cargo unit.
      type: string
      example: TRACTOR
      enum:
        - TRACTOR
        - TRAILER
        - TRUCK
    Version:
      type: integer
      description: Version of the entity, can be used for optimistic locking.
      example: 42
    Problem:
      type: object
      properties:
        title:
          type: string
          example: Validation exception
          description: A short, summary of the problem.
        detail:
          type: string
          description: A detailed explanation specific to this problem.
          example: The field contains invalid business formatting.
    ProblemWithViolations:
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          properties:
            violations:
              type: array
              items:
                $ref: '#/components/schemas/Violation'
    Violation:
      type: object
      properties:
        field:
          type: string
          example: path.to.field
        message:
          type: string
          example: Field is required
    CursorPagedDeployments:
      type: object
      properties:
        data:
          type: array
          description: |
            The set of results for the current page.
          items:
            $ref: '#/components/schemas/Deployment'
        cursors:
          $ref: '#/components/schemas/Cursors'
    Deployment:
      type: object
      properties:
        id:
          type: string
          description: The unique deployment ID.
          example: deployment-123
        resource_combination_id:
          type: string
          description: The ID of the associated resource combination, if any.
          example: rc-456
        availability_id:
          type: string
          description: The ID of the associated availability, if any.
          example: avail-789
        employee_id:
          type: string
          description: The ID of the employee assigned to this deployment.
          example: employee-42
        transport_resource_ids:
          type: array
          items:
            type: string
          description: The IDs of the transport resources assigned to this deployment.
          example:
            - truck-1
            - trailer-2
        start:
          $ref: '#/components/schemas/DeploymentStart'
        end:
          $ref: '#/components/schemas/DeploymentEnd'
        total_break_time:
          type: string
          description: >-
            Total break time during the deployment, formatted as ISO-8601
            duration.
          example: PT1H
        planning_id:
          type: string
          description: The ID of the planning that created this deployment, if any.
          example: planning-123
    DeploymentStart:
      type: object
      properties:
        at:
          type: string
          format: date-time
          description: When the deployment starts.
          example: '2021-01-01T08:00:00Z'
        location:
          $ref: '#/components/schemas/DeploymentLocation'
      required:
        - at
        - location
    DeploymentEnd:
      type: object
      properties:
        at:
          type: string
          format: date-time
          description: When the deployment ends.
          example: '2021-01-01T17:00:00Z'
        location:
          $ref: '#/components/schemas/DeploymentLocation'
      required:
        - at
        - location
    DeploymentLocation:
      type: object
      description: >
        Location for the deployment. For external deployments, either `address`
        or `home_base` must be provided, but not both.
      properties:
        home_base:
          $ref: '#/components/schemas/LinkedHomeBase'
          description: >
            The `business_id` of a known `HomeBase` in the system for this
            deployment location.
        address:
          $ref: '#/components/schemas/NamedGeoAddress'
          description: |
            Address for this deployment location.
    ExternalDeployment:
      type: object
      properties:
        employee:
          type: string
          description: The business ID of the employee for this deployment.
          example: employee-42
        transport_resources:
          type: array
          items:
            type: string
          description: The business IDs of the transport resources for this deployment.
          example:
            - truck-1
            - trailer-2
        start:
          $ref: '#/components/schemas/DeploymentStart'
        end:
          $ref: '#/components/schemas/DeploymentEnd'
        total_break_time:
          type: string
          description: >-
            Total break time during the deployment, formatted as ISO-8601
            duration.
          example: PT1H
      required:
        - employee
        - transport_resources
        - start
        - end
        - total_break_time
  responses:
    '400':
      description: Bad request
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemWithViolations'
    '401':
      description: Authentication required
    '404':
      description: Not found
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    '409':
      description: Conflict
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    '412':
      description: >
        This status is returned when an entity is updated with an outdated
        version in the If-Match header.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  headers:
    ETag:
      description: >-
        A weak Etag (ex `W/"<etag_value>"`) which contains the current version
        of the entity
      schema:
        type: string
        example: W/"25"
    Preference-Applied:
      description: >-
        Indicates whether a preference has been applied. (ex
        `return=representation`)
      schema:
        type: string
    Location:
      description: A URI to access the result of the operation.
      schema:
        type: string
        format: URI
  securitySchemes:
    clientCredentials:
      type: oauth2
      description: >
        This API uses OAuth2 with the Client Credentials flow for M2M
        communication. Client ID ans secret should be provided as a HTTP Basic
        Auth header.
      flows:
        clientCredentials:
          tokenUrl: >-
            https://auth.conundra.eu/auth/realms/prod/protocol/openid-connect/token
          scopes: {}
