Get Started in 7 Steps
Learn how to integrate PlanSolve's field service optimization using the REST API with PowerShell. This practical guide walks you through creating vehicles, visits, and solving optimization problems.
Code Example
{
"id": "tech1",
"homeLocation": [40.7128, -74.0060],
"skills": ["repair", "installation"],
"shifts": [{
"id": "morning",
"minStartTime": "2024-01-15T08:00:00",
"maxEndTime": "2024-01-15T17:00:00"
}]
}
What This Does
Each vehicle represents a technician with their capabilities. The homeLocation is where they start and stop their day, skills is a flat list of attributes that will be used to match to visits requiring those skills, and shifts specify when the technician is available for work.
Code Example
{
"id": "visit1",
"name": "AC Repair - Downtown Office",
"location": [40.7589, -73.9851],
"timeWindows": [{
"minStartTime": "2024-01-15T09:00:00",
"maxEndTime": "2024-01-15T17:00:00"
}],
"serviceDuration": "PT60M",
"priority": "HIGH",
"requiredSkills": ["repair"]
}
What This Does
Visits represent customer appointments. Time windows (optional) show when service can be performed, required skills (optional) ensure the right technician is assigned, and priority (optional) helps with scheduling order.
Code Example
{
"solver": "field_service",
"startDate": "2024-01-15",
"endDate": "2024-01-15",
"startDateTime": "2024-01-15T08:00:00",
"endDateTime": "2024-01-15T18:00:00",
"southwestCorner": [40.7000, -74.0200],
"northeastCorner": [40.8000, -73.9700],
"vehicles": [
{
"id": "tech1",
"homeLocation": [40.7128, -74.0060],
"skills": ["repair", "installation"],
"shifts": [{
"id": "morning",
"minStartTime": "2024-01-15T08:00:00",
"maxEndTime": "2024-01-15T17:00:00"
}]
}
],
"visits": [
{
"id": "visit1",
"name": "AC Repair - Downtown Office",
"location": [40.7589, -73.9851],
"timeWindows": [{
"minStartTime": "2024-01-15T09:00:00",
"maxEndTime": "2024-01-15T17:00:00"
}],
"serviceDuration": "PT60M",
"priority": "HIGH",
"requiredSkills": ["repair"]
}
]
}
What This Does
This is your complete optimization request. The solver field must be 'field_service', and you need to specify the geographic bounds (southwestCorner and northeastCorner) that contain all your locations. The API will return a job ID for tracking.
Code Example
$headers = @{
"X-API-KEY" = "your-api-key-here"
"Content-Type" = "application/json"
}
$body = @{
solver = "field_service"
startDate = "2024-01-15"
endDate = "2024-01-15"
startDateTime = "2024-01-15T08:00:00"
endDateTime = "2024-01-15T18:00:00"
southwestCorner = @(40.7000, -74.0200)
northeastCorner = @(40.8000, -73.9700)
vehicles = @(
@{
id = "tech1"
homeLocation = @(40.7128, -74.0060)
skills = @("repair", "installation")
shifts = @(
@{
id = "morning"
minStartTime = "2024-01-15T08:00:00"
maxEndTime = "2024-01-15T17:00:00"
}
)
}
)
visits = @(
@{
id = "visit1"
name = "AC Repair - Downtown Office"
location = @(40.7589, -73.9851)
timeWindows = @(
@{
minStartTime = "2024-01-15T09:00:00"
maxEndTime = "2024-01-15T17:00:00"
}
)
serviceDuration = "PT60M"
priority = "HIGH"
requiredSkills = @("repair")
}
)
} | ConvertTo-Json -Depth 10
$response = Invoke-RestMethod -Uri "https://api.plansolve.com/api/solve" -Method Post -Headers $headers -Body $body
$jobId = $response.jobId
Write-Host "Job submitted with ID: $jobId"
What This Does
Use PowerShell's Invoke-RestMethod to submit your request. The API will return a job ID that you'll use to track progress and retrieve results. Make sure to replace 'your-api-key-here' with your actual API key.
Code Example
$statusResponse = Invoke-RestMethod -Uri "https://api.plansolve.com/api/solve/$jobId" -Method Get -Headers $headers
$status = $statusResponse.status
Write-Host "Job status: $status"
# Possible statuses: PENDING, RUNNING, COMPLETED, FAILED
if ($status -eq "COMPLETED") {
Write-Host "Optimization completed successfully!"
} elseif ($status -eq "FAILED") {
Write-Host "Optimization failed. Check the error details."
} else {
Write-Host "Job is still processing. Status: $status"
}
What This Does
Poll the status endpoint to check if your optimization job has completed. The job will go through PENDING → RUNNING → COMPLETED states. For complex problems, this might take several minutes.
Code Example
if ($status -eq "COMPLETED") {
$results = Invoke-RestMethod -Uri "https://api.plansolve.com/api/solve/$jobId/result" -Method Get -Headers $headers
# Display the optimized routes
Write-Host "Optimized Routes:" -ForegroundColor Green
foreach ($vehicle in $results.vehicles) {
Write-Host "Vehicle: $($vehicle.id)" -ForegroundColor Yellow
Write-Host "Total driving time: $([math]::Round($vehicle.totalDrivingTimeSeconds / 60, 2)) minutes"
Write-Host "Route: $($vehicle.visits -join ' → ')"
Write-Host "Departure: $($vehicle.departureTime)"
Write-Host "Return: $($vehicle.arrivalTime)"
}
# Save results to file
$results | ConvertTo-Json -Depth 10 | Out-File -FilePath "optimization-results.json" -Encoding UTF8
Write-Host "Results saved to optimization-results.json" -ForegroundColor Green
}
What This Does
Once the job completes, retrieve the full results. The API returns detailed information about each vehicle's route, including visit order, timing, and driving distances. You can save this to a file for further processing.
Code Example
# Complete Field Service Optimization Script
$apiKey = "your-api-key-here"
$headers = @{
"X-API-KEY" = $apiKey
"Content-Type" = "application/json"
}
# Step 1: Create vehicles
$vehicles = @(
@{
id = "tech1"
homeLocation = @(40.7128, -74.0060)
skills = @("repair", "installation")
shifts = @(
@{
id = "morning"
minStartTime = "2024-01-15T08:00:00"
maxEndTime = "2024-01-15T17:00:00"
}
)
}
)
# Step 2: Create visits
$visits = @(
@{
id = "visit1"
name = "AC Repair - Downtown Office"
location = @(40.7589, -73.9851)
timeWindows = @(
@{
minStartTime = "2024-01-15T09:00:00"
maxEndTime = "2024-01-15T17:00:00"
}
)
serviceDuration = "PT60M"
priority = "HIGH"
requiredSkills = @("repair")
}
)
# Step 3: Create optimization request
$request = @{
solver = "field_service"
startDate = "2024-01-15"
endDate = "2024-01-15"
startDateTime = "2024-01-15T08:00:00"
endDateTime = "2024-01-15T18:00:00"
southwestCorner = @(40.7000, -74.0200)
northeastCorner = @(40.8000, -73.9700)
vehicles = $vehicles
visits = $visits
}
# Step 4: Submit request
$body = $request | ConvertTo-Json -Depth 10
$response = Invoke-RestMethod -Uri "https://api.plansolve.com/api/solve" -Method Post -Headers $headers -Body $body
$jobId = $response.jobId
Write-Host "Job submitted with ID: $jobId"
# Step 5: Monitor status
do {
Start-Sleep -Seconds 10
$statusResponse = Invoke-RestMethod -Uri "https://api.plansolve.com/api/solve/$jobId" -Method Get -Headers $headers
$status = $statusResponse.status
Write-Host "Job status: $status"
} while ($status -in @("PENDING", "RUNNING"))
# Step 6: Get results
if ($status -eq "COMPLETED") {
$results = Invoke-RestMethod -Uri "https://api.plansolve.com/api/solve/$jobId/result" -Method Get -Headers $headers
Write-Host "Optimization completed successfully!" -ForegroundColor Green
# Display results
foreach ($vehicle in $results.vehicles) {
Write-Host "Vehicle: $($vehicle.id)" -ForegroundColor Yellow
Write-Host "Route: $($vehicle.visits -join ' → ')"
}
} else {
Write-Host "Optimization failed with status: $status" -ForegroundColor Red
}
What This Does
This complete script demonstrates the entire workflow from creating vehicles and visits to retrieving optimized results. It includes error handling and status monitoring. You can use this as a template for your own implementations.
The API returns a structured response with two main sections: vehicles and visits. Here's what each contains:
{
"southWestCorner": [51.45, -0.15],
"northEastCorner": [51.55, -0.05],
"startDateTime": "2024-01-15T08:00:00",
"endDateTime": "2024-01-15T18:00:00",
"vehicles": [
{
"id": "1@2024-01-15",
"visits": ["1", "2", "3"],
"totalDrivingTimeSeconds": 5143,
"arrivalTime": "2024-01-15T15:59:38",
"departureTime": "2024-01-15T08:00:00"
}
],
"visits": [
{
"id": "1",
"name": "Task 1 - Day 1 Morning",
"vehicle": "1@2024-01-15",
"arrivalTime": "2024-01-15T08:16:11",
"startServiceTime": "2024-01-15T09:00:00",
"departureTime": "2024-01-15T09:30:00",
"drivingTimeSecondsFromPreviousStandstill": 971
}
]
}
Vehicles Section
- visitsArray of visit IDs in execution order
- totalDrivingTimeSecondsTotal driving time for the day
- arrivalTimeWhen the vehicle returns home
- departureTimeWhen the vehicle leaves home
Visits Section
- arrivalTimeWhen technician arrives at location
- startServiceTimeWhen service actually begins
- departureTimeWhen technician leaves location
- drivingTimeSecondsFromPreviousStandstillTravel time from previous stop
- vehicleWhich technician is assigned
Ready to Build?
Start with this example and gradually add more vehicles and visits as you become familiar with the API.
Need help? Check out our comprehensive documentation and examples.