---
title: "Synchronous Change and Re-evaluate"
method: POST
path: "/v2/vrp/jobs/{id}/change"
tags: ["Actions"]
---

# Synchronous Change and Re-evaluate

`POST /v2/vrp/jobs/{id}/change`

Apply manual changes to an existing VRP solution and re-evaluate synchronously. Fetches the original request and solution, applies your changes by setting plannedArrival/plannedResource, and returns the modified solution immediately. Use for 'what-if' scenario testing and dispatcher overrides.

## Path parameters

- `id` string, required

## Query parameters

- `millis` string, nullable

## Request body

- VrpChangeRequest — Request to manually modify an existing VRP solution and re-evaluate it. This endpoint allows you to move jobs to different positions/resources and see how it affects the solution quality. The changes are applied as soft constraints, meaning the solver will try to respect your manual placements while still ensuring feasibility (time windows, capacity, etc.). Use 'evaluate' for quick feedback (~200ms) or 'solve' to re-optimize other jobs around your changes (~5s).
  - `changes` JobChange[], required — List of job movements to apply. Each change specifies where to move a job in the solution. All 'after' references use positions from the ORIGINAL solution, not intermediate states. Changes are applied independently based on the original solution structure.
    - `job` string, required — Name/ID of the job to move (must exist in original solution)
    - `after` string, nullable — Position this job after another job in the route. - Use job name from ORIGINAL solution (not modified positions) - If null: job becomes first visit in the trip - If specified: resource is inferred from this job unless explicitly set
    - `resource` string, nullable — Target vehicle/resource name for this job. - If null: inferred from 'after' job's resource - If specified: overrides inferred resource - Must be valid resource from original request
    - `arrival` string, ISO8601 datetime string, nullable — Desired arrival time at this job (ISO8601 with timezone). - If null: automatically calculated from position (predecessor arrival + service + 30min buffer) - If specified: used as soft constraint target (solver will try to hit it but may deviate for feasibility) - Must be within resource's shift time
  - `operation` 'evaluate' | 'solve', required — Type of operation to perform after applying manual changes. - EVALUATE: Quick scoring/validation only. Returns modified solution with score but no optimization. Use this when you just want to see the impact of your changes. (~200ms) - SOLVE: Re-optimizes all non-manually-placed jobs around your changes. Your manual placements stay as soft constraints, but other jobs may move to improve overall score. Use this when you want the solver to fix up the rest of the solution. (~5s with default termination)

## Response `200`

Modified solution with changes applied

- OnRouteResponse — OnRoute response from solve
  - `id` string, nullable — Id of the solve job
  - `status` 'ERROR' | 'QUEUED' | 'SOLVING' | 'SOLVED', nullable — Status of the solve job.
  - `score` object, nullable — The score of a solution shows how good this solution is w.r.t all the constraints. All solvers try to maximize the score.
    - `hardScore` integer, nullable — The score of the constraints that are hard. This should be 0 in order to be feasible.
    - `mediumScore` integer, nullable — The score of the constraints that are medium.
    - `softScore` integer, nullable — The score of the constraints that are soft.
    - `feasible` boolean, nullable
  - `unresolved` unknown
  - `trips` Trip[], required — Actual solution: trips per shift/day and per resource
    - `visits` Visit[], required — List of visits for a resource and a date.
      - `arrival` string, date-time, nullable — Actual arrival date-time
      - `serviceTime` integer, nullable — Total service time of that job in seconds
      - `travelTime` integer, nullable — Total travel time to that job in seconds
      - `distance` integer, nullable — Total travel distance to that job in meters
      - `job` string, nullable — Job
      - `activity` string, nullable — The activity to
      - `location` object, nullable — Geographical Location in WGS-84
        - `latitude` number, double — Latitude
        - `longitude` number, double — Longitude
        - `h3Index` integer, nullable — H3 hexagon index at resolution 9 (optional)
      - `latlon` number[], nullable — Snapped Latlng. When we get your lat/lon in input, we snap it on our map to a valid point in the graph. We return all snapped points.
      - `snappedLocation` object, nullable — Geographical Location in WGS-84
        - `latitude` number, double — Latitude
        - `longitude` number, double — Longitude
        - `h3Index` integer, nullable — H3 hexagon index at resolution 9 (optional)
      - `breakTime` integer, nullable — Break time in seconds
      - `waitTime` integer, nullable — Wait time in seconds
    - `resource` string, nullable — Resource
    - `date` string, ISO8601 date string, nullable — Date
    - `departureTime` string, ISO8601 datetime string, nullable — Departure date-time
    - `waitTime` integer, nullable — Wait time in seconds
    - `travelTime` integer, nullable — Travel time in seconds
    - `workTime` integer, nullable — Work time in seconds
    - `serviceTime` integer, nullable — Service time in seconds
    - `polyline` string, nullable — Polyline of the trip
    - `occupancy` number, double, nullable — How full this trip is in terms of work time over capacity. Eg 80%
    - `start` Visit — Single visit for a resource. Holds information of the actual arrival time, the job, the location and the latlng.
      - `arrival` string, date-time, nullable — Actual arrival date-time
      - `serviceTime` integer, nullable — Total service time of that job in seconds
      - `travelTime` integer, nullable — Total travel time to that job in seconds
      - `distance` integer, nullable — Total travel distance to that job in meters
      - `job` string, nullable — Job
      - `activity` string, nullable — The activity to
      - `location` object, nullable — Geographical Location in WGS-84
        - `latitude` number, double — Latitude
        - `longitude` number, double — Longitude
        - `h3Index` integer, nullable — H3 hexagon index at resolution 9 (optional)
      - `latlon` number[], nullable — Snapped Latlng. When we get your lat/lon in input, we snap it on our map to a valid point in the graph. We return all snapped points.
      - `snappedLocation` object, nullable — Geographical Location in WGS-84
        - `latitude` number, double — Latitude
        - `longitude` number, double — Longitude
        - `h3Index` integer, nullable — H3 hexagon index at resolution 9 (optional)
      - `breakTime` integer, nullable — Break time in seconds
      - `waitTime` integer, nullable — Wait time in seconds
    - `end` Visit — Single visit for a resource. Holds information of the actual arrival time, the job, the location and the latlng.
      - `arrival` string, date-time, nullable — Actual arrival date-time
      - `serviceTime` integer, nullable — Total service time of that job in seconds
      - `travelTime` integer, nullable — Total travel time to that job in seconds
      - `distance` integer, nullable — Total travel distance to that job in meters
      - `job` string, nullable — Job
      - `activity` string, nullable — The activity to
      - `location` object, nullable — Geographical Location in WGS-84
        - `latitude` number, double — Latitude
        - `longitude` number, double — Longitude
        - `h3Index` integer, nullable — H3 hexagon index at resolution 9 (optional)
      - `latlon` number[], nullable — Snapped Latlng. When we get your lat/lon in input, we snap it on our map to a valid point in the graph. We return all snapped points.
      - `snappedLocation` object, nullable — Geographical Location in WGS-84
        - `latitude` number, double — Latitude
        - `longitude` number, double — Longitude
        - `h3Index` integer, nullable — H3 hexagon index at resolution 9 (optional)
      - `breakTime` integer, nullable — Break time in seconds
      - `waitTime` integer, nullable — Wait time in seconds
    - `distance` integer, nullable
  - `totalWaitTimeInSeconds` integer, nullable — Wait time for all resources
  - `occupancy` number, double, nullable — How full this schedule is in terms of work time (incl travel) over capacity. Eg 80%
  - `totalTravelDistanceInMeters` integer, nullable — Travel distance for all resources in meters
  - `totalTravelTimeInSeconds` integer, nullable — Travel time for all resources
  - `totalServiceTimeInSeconds` integer, nullable — Service time for all resources
  - `unserved` string[], nullable — Unserved jobs
  - `unservedReasons` object, nullable — Reasons why jobs could not be served, mapped by job name
  - `suggestions` SuggestionDto[], nullable — List of suggested assignments returned by suggest api call
    - `score` Score, required — The score of a solution shows how good this solution is w.r.t all the constraints. All solvers try to maximize the score.
      - `hardScore` integer, nullable — The score of the constraints that are hard. This should be 0 in order to be feasible.
      - `mediumScore` integer, nullable — The score of the constraints that are medium.
      - `softScore` integer, nullable — The score of the constraints that are soft.
      - `feasible` boolean, nullable
    - `assignments` JobAssignment[], required
      - `job` string, required — Job
      - `resource` string, required — Resource
      - `suggestedArrival` string, ISO8601 datetime string, nullable — Suggested arrival date-time
      - `latestArrival` string, ISO8601 datetime string, nullable — Latest arrival date-time
      - `executedAfter` string, required — Executed after date-time
      - `score` object, nullable — The score of a solution shows how good this solution is w.r.t all the constraints. All solvers try to maximize the score.
        - `hardScore` integer, nullable — The score of the constraints that are hard. This should be 0 in order to be feasible.
        - `mediumScore` integer, nullable — The score of the constraints that are medium.
        - `softScore` integer, nullable — The score of the constraints that are soft.
        - `feasible` boolean, nullable
      - `scoreExplanation` object — Unresolved constraints in this alternative solution
        - `constraint` 'TRIP_CAPACITY' | 'RESOURCE_CAPACITY' | 'RESOURCE_CAPACITY2' | 'TRAVEL_TIME' | 'TYPE_REQUIREMENT' | 'TAG_SOFT' | 'TAG_HARD' | 'TYPE_REQUIREMENT_SOFT' | 'END_LOCATION_TRAVEL_TIME' | 'TIME_WINDOW_CONFLICT' | 'SHIFT_END_CONFLICT' | 'OVERTIME_END_CONFLICT' | 'RESOURCE_USAGE' | 'URGENCY' | 'PREFERRED_RESOURCE_CONFLICT' | 'ALLOWED_RESOURCES' | 'DISALLOWED_RESOURCES' | 'REGION_TIME' | 'FAIR_WORK' | 'UNSERVED_JOBS' | 'RESOURCE_ACTIVATION' | 'OPEN_DAYS' | 'JOB_PRECEDENCE' | 'JOB_DAY_INDEX' | 'DATE_TIME_WINDOW_CONFLICT' | 'DATE_TIME_WINDOW_CONFLICT_SOFT' | 'LINKED_JOB_CONFLICT' | 'PLANNED_RESOURCE' | 'PLANNED_ARRIVAL' | 'PLANNED_DATE' | 'WORKING_TIME' | 'HARD_JOBS' | 'MAX_DRIVE_TIME' | 'MAX_DRIVE_TIME_JOB' | 'FAIR_TOTAL_WORK' | 'RESOURCE_PERIOD_MAX_SERVICE_TIME' | 'RESOURCE_PERIOD_MAX_DRIVE_TIME' | 'RESOURCE_PERIOD_MAX_WORK_TIME' | 'RESOURCE_PERIOD_MIN_SERVICE_TIME' | 'RESOURCE_PERIOD_MIN_DRIVE_TIME' | 'RESOURCE_PERIOD_MIN_WORK_TIME' | 'MINIMISE_TRIP_USAGE' | 'DELIVERY_NOT_ON_SAME_VEHICLE' | 'DELIVERY_BEFORE_PICKUP' | 'SAME_TRIP' | 'SEQUENCE' | 'SAME_TIME' | 'NEIGHBOR' | 'DIRECT_SEQUENCE' | 'SAME_RESOURCE' | 'WAIT_TIME' | 'DRIVE_TIME' | 'HOURLY_COST' | 'RANKING_SOFT' | 'FAIR_COMPLEXITY_PER_TRIP' | 'FAIR_COMPLEXITY_PER_RESOURCE' | 'RESOURCE_PERIOD_MIN_COMPLEXITY' | 'RESOURCE_PERIOD_MAX_COMPLEXITY' | 'RESOURCE_COMPATIBILITY' | 'JOBTYPE_VIOLATION' | 'GROUP_SEQUENCE' | 'JOB_PROXIMITY', required — Types of constraints that can be violated in a routing solution
        - `score` string, required — Score impact of this conflict.
      - `suggestedInitialArrival` string, date-time
      - `violations` Unresolved[], nullable
        - `constraint` 'TRIP_CAPACITY' | 'RESOURCE_CAPACITY' | 'RESOURCE_CAPACITY2' | 'TRAVEL_TIME' | 'TYPE_REQUIREMENT' | 'TAG_SOFT' | 'TAG_HARD' | 'TYPE_REQUIREMENT_SOFT' | 'END_LOCATION_TRAVEL_TIME' | 'TIME_WINDOW_CONFLICT' | 'SHIFT_END_CONFLICT' | 'OVERTIME_END_CONFLICT' | 'RESOURCE_USAGE' | 'URGENCY' | 'PREFERRED_RESOURCE_CONFLICT' | 'ALLOWED_RESOURCES' | 'DISALLOWED_RESOURCES' | 'REGION_TIME' | 'FAIR_WORK' | 'UNSERVED_JOBS' | 'RESOURCE_ACTIVATION' | 'OPEN_DAYS' | 'JOB_PRECEDENCE' | 'JOB_DAY_INDEX' | 'DATE_TIME_WINDOW_CONFLICT' | 'DATE_TIME_WINDOW_CONFLICT_SOFT' | 'LINKED_JOB_CONFLICT' | 'PLANNED_RESOURCE' | 'PLANNED_ARRIVAL' | 'PLANNED_DATE' | 'WORKING_TIME' | 'HARD_JOBS' | 'MAX_DRIVE_TIME' | 'MAX_DRIVE_TIME_JOB' | 'FAIR_TOTAL_WORK' | 'RESOURCE_PERIOD_MAX_SERVICE_TIME' | 'RESOURCE_PERIOD_MAX_DRIVE_TIME' | 'RESOURCE_PERIOD_MAX_WORK_TIME' | 'RESOURCE_PERIOD_MIN_SERVICE_TIME' | 'RESOURCE_PERIOD_MIN_DRIVE_TIME' | 'RESOURCE_PERIOD_MIN_WORK_TIME' | 'MINIMISE_TRIP_USAGE' | 'DELIVERY_NOT_ON_SAME_VEHICLE' | 'DELIVERY_BEFORE_PICKUP' | 'SAME_TRIP' | 'SEQUENCE' | 'SAME_TIME' | 'NEIGHBOR' | 'DIRECT_SEQUENCE' | 'SAME_RESOURCE' | 'WAIT_TIME' | 'DRIVE_TIME' | 'HOURLY_COST' | 'RANKING_SOFT' | 'FAIR_COMPLEXITY_PER_TRIP' | 'FAIR_COMPLEXITY_PER_RESOURCE' | 'RESOURCE_PERIOD_MIN_COMPLEXITY' | 'RESOURCE_PERIOD_MAX_COMPLEXITY' | 'RESOURCE_COMPATIBILITY' | 'JOBTYPE_VIOLATION' | 'GROUP_SEQUENCE' | 'JOB_PROXIMITY', required — Types of constraints that can be violated in a routing solution
        - `score` string, required — Score impact of this conflict.
  - `messages` string[], nullable — Events and warnings generated during the solver execution
  - `violations` ViolatedConstraint[], nullable
    - `name` string, nullable, required — Name of the constraint.
    - `value` integer, nullable, required — Value of the unresolved constraint. The higher, the more deviation from perfection this constraint has.
    - `level` 'HARD' | 'SOFT' | 'MEDIUM', nullable, required — Level of unresolved constraint.
  - `workloadFairness` number, double, nullable

## Other responses

- `400` — Job not found or not solved
- `404` — Job ID not found
- `427` — Too many requests.
- `500` — Internal error

## Changes

- **2025-11-27** `2e6752ec1b09` — 6 info
  - added the optional property `trips/items/end/anyOf[#/components/schemas/Visit]/location/anyOf[#/components/schemas/Location]/h3Index` to the response with the `200` status
  - added the optional property `trips/items/end/anyOf[#/components/schemas/Visit]/snappedLocation/anyOf[#/components/schemas/Location]/h3Index` to the response with the `200` status
  - added the optional property `trips/items/start/anyOf[#/components/schemas/Visit]/location/anyOf[#/components/schemas/Location]/h3Index` to the response with the `200` status
  - added the optional property `trips/items/start/anyOf[#/components/schemas/Visit]/snappedLocation/anyOf[#/components/schemas/Location]/h3Index` to the response with the `200` status
  - …2 more
- **2025-11-27** `a35725e2af55` — 4 warning
  - added the new `GROUP_SEQUENCE` enum value to the `suggestions/items/assignments/items/scoreExplanation/constraint` response property for the response status `200`
  - added the new `GROUP_SEQUENCE` enum value to the `suggestions/items/assignments/items/violations/items/constraint` response property for the response status `200`
  - added the new `JOB_PROXIMITY` enum value to the `suggestions/items/assignments/items/scoreExplanation/constraint` response property for the response status `200`
  - added the new `JOB_PROXIMITY` enum value to the `suggestions/items/assignments/items/violations/items/constraint` response property for the response status `200`
- …earlier changes not shown

[Full history](https://skmtc.dev/solvice/apis/vrp-api/changes/v2/vrp/jobs/:id/change/post.md)

---

[API](https://skmtc.dev/solvice/apis/vrp-api.md) · [All operations](https://skmtc.dev/solvice/apis/vrp-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/solvice/vrp-api/revisions/d77ac8b3d302/schema)
