Optimize: Replan
/api/v1/optimize/replanLive re-optimization: accept the current real-world execution state (completed jobs, vehicle positions, new urgent jobs, cancellations) and return an updated plan for the remaining work.
Description
Internally, build_replan_request() transforms the original_request into a fresh OptimizationRequest: it strips completed and cancelled jobs (and any shipment referencing them), injects new_jobs, and advances each positioned vehicle's start_location and time_window.start to its current position and time (preserving the original shift end). Any existing depot_index/start_depot_id on an advanced resource is cleared so the explicit start_location wins. The transformed request is then solved normally via the standard pipeline.
Two ways to express completed work
| Field | Behavior |
|---|---|
| completed_job_ids | Simple list of job IDs already served. vehicle_positions must be supplied separately to advance each vehicle's start. |
| completed_jobs | Richer list of {{job_id, resource_id, started_at, finished_at}}. The engine automatically derives each resource's current position and time from the completed job with the latest finished_at on that resource. An explicit vehicle_positions entry for the same resource still overrides the derived value. |
Request body: ReplanRequest
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| original_request | OptimizationRequest | required | - | The full original problem definition. |
| completed_job_ids | string[] | optional | [] | Jobs already served; excluded from the re-solve entirely. |
| completed_jobs | CompletedJob[] | optional | [] | Richer completed-job records with actual start/end times; see above. |
| cancelled_job_ids | string[] | optional | [] | Jobs to drop; excluded and not counted as unserved. |
| vehicle_positions | VehiclePosition[] | optional | [] | Each: {{resource_id, location_index, current_time}}. Overrides any position derived from completed_jobs for the same resource. |
| new_jobs | Job[] | optional | [] | Urgent jobs added after the original plan was made. |
Response
Full OptimizationResponse for the remaining work.
Examples
Example: mid-day replan with one completed job and one urgent insertion
curl -X POST https://api.fieldgenius.be/api/v1/optimize/replan \
-H "Content-Type: application/json" \
-H "X-API-Key: your-adapter-key" \
-H "X-Client-Key: your-client-key" \
-d '{
"original_request": {
"travel": { "distance_matrix": [[0,6,9,7,5],[6,0,5,4,8],[9,5,0,6,7],[7,4,6,0,3],[5,8,7,3,0]] },
"resources": [{ "id": "van-01", "depot_index": 0, "time_window": { "start": 0, "end": 28800 } }],
"jobs": [
{ "id": "stop-a", "location_index": 1 },
{ "id": "stop-b", "location_index": 2 },
{ "id": "stop-c", "location_index": 3 }
]
},
"completed_jobs": [
{ "job_id": "stop-a", "resource_id": "van-01", "started_at": 720, "finished_at": 900 }
],
"new_jobs": [
{ "id": "stop-urgent-d", "location_index": 4, "mandatory": true }
]
}'import httpx
payload = {
"original_request": {
"travel": {"distance_matrix": [[0, 6, 9, 7, 5], [6, 0, 5, 4, 8],
[9, 5, 0, 6, 7], [7, 4, 6, 0, 3], [5, 8, 7, 3, 0]]},
"resources": [{"id": "van-01", "depot_index": 0, "time_window": {"start": 0, "end": 28800}}],
"jobs": [
{"id": "stop-a", "location_index": 1},
{"id": "stop-b", "location_index": 2},
{"id": "stop-c", "location_index": 3},
],
},
"completed_jobs": [
{"job_id": "stop-a", "resource_id": "van-01", "started_at": 720, "finished_at": 900}
],
"new_jobs": [{"id": "stop-urgent-d", "location_index": 4, "mandatory": True}],
}
headers = {"X-API-Key": "your-adapter-key", "X-Client-Key": "your-client-key"}
resp = httpx.post("https://api.fieldgenius.be/api/v1/optimize/replan", json=payload, headers=headers)
print(resp.json()["routes"])Errors
| Status | Code | Resolution |
|---|---|---|
| 422 | VALIDATION_ERROR | Raised (via ValueError/KeyError in build_replan_request) when a completed/cancelled job ID or vehicle position references a resource/job not in original_request. |
| 422 | SOLVER_INFEASIBLE | The advanced positions and remaining time budget cannot serve all mandatory remaining jobs. |
See Example: Live Replanning for two more worked scenarios (urgent injection with cancellation, and an all-vehicles-mid-route emergency).