Most routing APIs treat pickup-and-delivery as one shape: pick up here, drop off there. Real field service, last-mile, healthcare, and waste operations are messier. Five Job Relations patterns (same-vehicle, predecessor/successor, direct adjacency, sequence chains, same-time) cover what real paired and sequenced work needs from an embedded routing engine.

A field service technician picks up a replacement compressor at the depot at 7am. By 10am, she's at a commercial HVAC site installing it. By 2pm, she's at a different depot returning the old compressor for refurbishment. By 4pm, she's at a small business doing a routine maintenance call.
Four stops. Four very different jobs. Two of them are not independent.
The compressor pickup at 7am only exists because of the install at 10am. The depot return at 2pm only exists because of the install at 10am. If the install gets rescheduled, those two stops have to move with it. If the install gets reassigned to a different vehicle, both stops have to follow. If the order gets reversed because of an emergency, the pickup has to slide earlier.
That's not a routing problem you can solve with stops and time windows alone.
Most routing APIs that handle the pickup-and-delivery pattern treat it as one shape. Pick something up here. Drop it off there. Same vehicle. The pickup must precede the delivery.
That's enough for parcel and food delivery, where the pattern is genuinely one-to-one. Pick up a package at the warehouse, drop it at the customer.
For real field service, last-mile with depot returns, non-emergency medical transport, and waste collection, the pattern is messier.
Each of those is a sequenced relationship between two or more jobs. Each has a different rule. None of them collapses cleanly into the basic PDP shape.
Job Relations is the constraint layer in the Solvice VRP API that defines how jobs depend on each other. Five relationship types cover the operational patterns above.
Two jobs must be assigned to the same resource. Use when a technician must perform both halves of a paired task, or when picked-up inventory has to travel with the vehicle that picked it up.
Job A must be scheduled before Job B. The two can be on the same vehicle or on different vehicles. The only constraint is order.
Used for: install before training visit, pickup before delivery anywhere on the network, initial assessment before follow-up service.
Job B must come immediately after Job A on the same vehicle's route. No stops between them.
Used for: paired actions that need adjacency (drop the patient, then drive directly back to base), depot dump cycles in waste collection, point-of-care services that span back-to-back stops.
Three or more jobs locked into an explicit order, across one or more vehicles.
Used for: install then configure then train workflows, multi-day projects with day-1 / day-2 / day-3 stops, hospital discharge then ride home then med pickup chains.
Two jobs must start within a defined window of each other (same minute, same hour). Used for paired field workers (two technicians needed to lift a unit), simultaneous events that must converge.
The relationship definitions aren't the point. The point is that the solver respects them automatically when the live plan changes.
A re-solve, a synchronous re-optimization call, a Suggest insertion. The relationships travel with the jobs. If a predecessor slips two hours, every successor in the chain shifts in tandem. If a same-vehicle pair gets reassigned, both halves move together. If a direct-successor chain is interrupted by a real-time insertion, the solver finds the next-best slot that preserves the adjacency, or it surfaces the trade-off explicitly.
This is the difference between a routing API that models field work and one that approximates it.
The OEM platforms going furthest with Job Relations are running patterns like these:
In each case, the platform exposes Job Relations as a first-class concept to its end users. The operators describe the relationship in business terms ("the pickup must happen before the install, on the same vehicle, on the same day"). The platform translates that into Job Relations constraints. The solver does the rest.
A common workaround for paired work in routing APIs that lack explicit relations is to model both halves as a single virtual job with a fixed duration. It looks clean. It also breaks the moment one half needs to be re-scheduled, re-assigned, or evaluated independently.
Real operations require both halves to stay visible to the solver as separate entities, with the relationship modelled as a constraint instead of folded into the geometry. That's what Job Relations gives you.
If you're modelling field work or paired logistics in your platform and you've hit the ceiling of basic pickup-and-delivery, talk to us.


