> ## Documentation Index
> Fetch the complete documentation index at: https://docs.solvice.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Job Relations

> Define complex dependencies and constraints between jobs in your routes

# Job Relations

Job relations allow you to define dependencies and constraints between multiple jobs in your VRP optimization. These relations ensure that certain business rules are respected when the solver creates routes.

## Overview

Job relations are defined using the `relations` array within each job. Each relation specifies:

* A `type` indicating the constraint type
* A list of `jobs` that are part of this relation
* Additional parameters specific to each relation type

```json theme={null}
{
  "resources": [
    {
      "name": "Vehicle 1",
      "shifts": [
        {
          "from": "2024-03-15T08:00:00Z",
          "to": "2024-03-15T18:00:00Z"
        }
      ]
    }
  ],
  "jobs": [
    {
      "name": "pickup-1",
      "location": {"lat": 52.5230, "lon": 13.4010}
    },
    {
      "name": "delivery-1",
      "location": {"lat": 52.5170, "lon": 13.3880},
    }
  ],
    "relations": [
{
    "type": "SEQUENCE",
    "jobs": ["pickup-1", "delivery-1"],
    "minTimeInterval": 0,
    "maxTimeInterval": 3600
}
    ]
}
```

## Available Relation Types

### SEQUENCE

Jobs must be visited in the specified order, but other jobs can be scheduled between them.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "SEQUENCE",
    "jobs": ["job-1", "job-2", "job-3"],
    "minTimeInterval": 300,
    "maxTimeInterval": 7200
  }
  ```

  ```json Parameters theme={null}
  {
    "minTimeInterval": "Minimum seconds between consecutive jobs (optional)",
    "maxTimeInterval": "Maximum seconds between consecutive jobs (optional)"
  }
  ```
</CodeGroup>

<Tip>
  The time intervals specify the gap between when one job ends and the next job begins. This is useful for ensuring adequate travel time or preparation between related tasks.
</Tip>

**Use Cases:**

* Multi-stop deliveries where order matters
* Service appointments with dependencies
* Workflows requiring specific sequences

### DIRECT\_SEQUENCE

Jobs must be visited in the exact order with no other jobs scheduled between them.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "DIRECT_SEQUENCE",
    "jobs": ["pickup", "delivery"]
  }
  ```
</CodeGroup>

**Use Cases:**

* Immediate transfer operations
* Time-critical handoffs
* Continuous processes that cannot be interrupted

### SAME\_TRIP

All jobs in the relation must be assigned to the same route/trip.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "SAME_TRIP",
    "jobs": ["pickup-1", "pickup-2", "delivery-hub"],
    "partialPlanning": false
  }
  ```

  ```json Parameters theme={null}
  {
    "partialPlanning": "Allow solver to plan subset when overconstrained (default: false)"
  }
  ```
</CodeGroup>

**Use Cases:**

* Consolidation requirements
* Grouped deliveries
* Ensuring related tasks stay together

### SAME\_TIME

Jobs must start or end within a specified time window of each other, with optional minimum time intervals.
Optionally enforces resource compatibility constraints to ensure only authorized resources work together.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "SAME_TIME",
    "jobs": ["install-1", "install-2"],
    "minTimeInterval": 300,
    "maxTimeInterval": 600,
    "maxWaitingTime": 3600,
    "timeInterval": "FROM_ARRIVAL",
    "enforceCompatibility": true
  }
  ```

  ```json Parameters theme={null}
  {
    "minTimeInterval": "Minimum seconds between job times (optional)",
    "maxTimeInterval": "Maximum seconds between job times",
    "maxWaitingTime": "Maximum allowed waiting time",
    "timeInterval": "FROM_ARRIVAL or FROM_DEPARTURE",
    "enforceCompatibility": "Enforce resource compatibility constraints (optional, default: false)"
  }
  ```
</CodeGroup>

<Note>
  When `enforceCompatibility` is true, the solver ensures that only compatible resources work together on SAME\_TIME related jobs. Resources must define their compatible partners using the `compatibleResources` field.

  **Minimum Time Interval Behavior:**
  When `minTimeInterval` is specified, the last job in the `jobs` array must arrive/depart at least `minTimeInterval` seconds after all other jobs. This is useful for staggered arrivals or ensuring adequate spacing between operations.
</Note>

**Use Cases:**

* Synchronized operations
* Team installations
* Coordinated services
* Healthcare teams requiring authorized personnel
* Security operations with supervision requirements
* Training scenarios with approved mentors
* Staggered arrivals at loading docks
* Sequential processing with minimum gaps

**Example with Minimum Time Interval:**

```json theme={null}
{
  "type": "SAME_TIME",
  "jobs": ["truck-1-arrival", "truck-2-arrival", "dock-preparation"],
  "minTimeInterval": 300,
  "maxTimeInterval": 600,
  "maxWaitingTime": 3600,
  "timeInterval": "FROM_ARRIVAL"
}
```

In this example, if "dock-preparation" is the last job in the array, it will arrive at least 300 seconds (5 minutes) after both truck arrivals, ensuring the dock is ready when preparation begins.

### SAME\_RESOURCE

All jobs must be assigned to the same resource/vehicle (can be on different days).

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "SAME_RESOURCE",
    "jobs": ["service-1", "service-2", "service-3"],
    "resource": "technician-123"
  }
  ```

  ```json Parameters theme={null}
  {
    "resource": "Optional: specific resource name"
  }
  ```
</CodeGroup>

**Use Cases:**

* Customer preference for specific technician
* Specialized equipment requirements
* Continuity of service

### PICKUP\_AND\_DELIVERY

Enforces that pickup happens before delivery, with both assigned to the same resource.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "PICKUP_AND_DELIVERY",
    "jobs": ["pickup-order-123", "delivery-order-123"]
  }
  ```
</CodeGroup>

**Use Cases:**

* Courier services
* Equipment rental returns
* Any pickup/delivery pair

### NEIGHBOR

Jobs should be scheduled consecutively by the same resource (flexible order).

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "NEIGHBOR",
    "jobs": ["stop-1", "stop-2", "stop-3"]
  }
  ```
</CodeGroup>

**Use Cases:**

* Minimizing travel between related stops
* Clustered service areas
* Efficiency optimization

### SAME\_DAY

All jobs must be completed on the same calendar day.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "SAME_DAY",
    "jobs": ["morning-pickup", "afternoon-delivery"]
  }
  ```
</CodeGroup>

**Use Cases:**

* Same-day delivery services
* Daily batch processing
* Time-sensitive operations

### GROUP\_SEQUENCE

Enforces ordering between groups of jobs based on tags.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "GROUP_SEQUENCE",
    "tags": ["priority-high", "priority-normal", "priority-low"]
  }
  ```

  ```json Job Definition theme={null}
  {
    "name": "urgent-delivery",
    "tags": [{"name": "priority-high"}],
    "location": {"lat": 52.5200, "lon": 13.4050}
  }
  ```
</CodeGroup>

**Use Cases:**

* Priority-based scheduling
* Phased operations
* Category-based ordering

### FIRST\_JOB

Ensures a job is scheduled as the first stop for a resource.

<CodeGroup>
  ```json Request theme={null}
  {
    "type": "FIRST_JOB",
    "jobs": ["warehouse-pickup"]
  }
  ```
</CodeGroup>

**Use Cases:**

* Morning warehouse pickups
* Mandatory first stops
* Initial setup requirements

## Complete Example

Here's a comprehensive example showing multiple relation types working together:

<CodeGroup>
  ```json theme={null}
  {
    "resources": [
      {
        "name": "vehicle-1",
        "capacity": [1000],
        "shifts": [
          {
            "start": {
              "location": {"lat": 52.5200, "lon": 13.4050},
              "time": "2024-03-15T08:00:00Z"
            },
            "end": {
              "location": {"lat": 52.5200, "lon": 13.4050},
              "time": "2024-03-15T18:00:00Z"
            }
          }
        ]
      }
    ],
    "jobs": [
      {
        "name": "warehouse-pickup",
        "location": {"lat": 52.5200, "lon": 13.4050},
        "serviceDurationInSeconds": 1800
  },
      {
        "name": "customer-pickup-1",
        "location": {"lat": 52.5230, "lon": 13.4010},
        "serviceDurationInSeconds": 600,
      },
      {
        "name": "customer-delivery-1",
        "location": {"lat": 52.5170, "lon": 13.3880},
        "serviceDurationInSeconds": 600,
        "activity": "DELIVERY"
      },
      {
        "name": "customer-pickup-2",
        "location": {"lat": 52.5280, "lon": 13.4120},
        "serviceDurationInSeconds": 600,
        "tags": [{"name": "express"}]
      },
      {
        "name": "customer-delivery-2",
        "location": {"lat": 52.5090, "lon": 13.3760},
        "serviceDurationInSeconds": 600,
        "tags": [{"name": "express"}]
      },
      {
        "name": "return-to-warehouse",
        "location": {"lat": 52.5200, "lon": 13.4050},
        "serviceDurationInSeconds": 1800,
        "windows": [["2024-03-15T16:00:00Z", "2024-03-15T18:00:00Z"]]
      }
    ],
      "relations": [
  {
      "type": "PICKUP_AND_DELIVERY",
      "jobs": ["customer-pickup-1", "customer-delivery-1"]
  },
  {
      "type": "SAME_DAY",
      "jobs": ["customer-pickup-1", "customer-delivery-1", "customer-pickup-2", "customer-delivery-2"]
  },
  {
      "type": "PICKUP_AND_DELIVERY",
      "jobs": ["customer-pickup-2", "customer-delivery-2"]
  },
  {
      "type": "SEQUENCE",
      "jobs": ["customer-pickup-2", "customer-delivery-2"],
      "maxTimeInterval": 3600
  },
  {
      "type": "FIRST_JOB",
      "jobs": ["warehouse-pickup"]
  }
      ]
  }
  ```
</CodeGroup>

## Resource Compatibility

Resource compatibility allows you to control which resources can work together on SAME\_TIME related jobs. This is essential for scenarios requiring specific team compositions, authorization levels, or supervision requirements.

### Configuring Resource Compatibility

Add the `compatibleResources` field to your resource definitions:

<CodeGroup>
  ```json Resources with Compatibility theme={null}
  {
    "resources": [
      {
        "name": "Dr-Smith",
        "compatibleResources": ["Nurse-John", "Nurse-Mary"],
        "shifts": [...]
      },
      {
        "name": "Nurse-John",
        "compatibleResources": ["Dr-Smith", "Dr-Jones"],
        "shifts": [...]
      }
    ]
  }
  ```
</CodeGroup>

### Compatibility Rules

1. **Mutual Compatibility**: For two resources to work together, both must list each other
2. **One-Way Compatibility**: Useful for supervision scenarios where only one resource needs authorization
3. **Open Compatibility**: Resources without `compatibleResources` can work with anyone

### Example: Healthcare Team

<CodeGroup>
  ```json theme={null}
  {
    "resources": [
      {
        "name": "dr-smith",
        "compatibleResources": ["nurse-john", "nurse-mary"],
        "shifts": [
          {
            "from": "2024-03-15T08:00:00Z",
            "to": "2024-03-15T17:00:00Z"
          }
        ]
      },
      {
        "name": "nurse-john",
        "compatibleResources": ["dr-smith"],
        "shifts": [
          {
            "from": "2024-03-15T08:00:00Z",
            "to": "2024-03-15T17:00:00Z"
          }
        ]
      },
      {
        "name": "nurse-mary",
        "compatibleResources": ["dr-smith"],
        "shifts": [
          {
            "from": "2024-03-15T08:00:00Z",
            "to": "2024-03-15T17:00:00Z"
          }
        ]
      }
    ],
    "jobs": [
      {
        "name": "patient-visit-1",
        "location": {"lat": 52.5230, "lon": 13.4010},
        "serviceDurationInSeconds": 1800,
      },
      {
        "name": "patient-visit-2",
        "location": {"lat": 52.5240, "lon": 13.4020},
        "serviceDurationInSeconds": 1800
      }
    ],
      "relations": [
  {
      "type": "SAME_TIME",
      "jobs": ["patient-visit-1", "patient-visit-2"],
      "enforceCompatibility": true
  }
      ]
  }
  ```
</CodeGroup>

### Example: Security Team with Supervision

<CodeGroup>
  ```json theme={null}
  {
    "resources": [
      {
        "name": "Senior Guard",
        "compatibleResources": ["Junior Guard 1", "Junior Guard 2", "Junior Guard 3"],
        "shifts": [...]
      },
      {
        "name": "Junior Guard 1",
        "compatibleResources": ["Senior Guard"],
        "shifts": [...]
      },
      {
        "name": "Trainee",
        "compatibleResources": [],  // Can only work with senior guard (one-way)
        "shifts": [...]
      }
    ],
    "jobs": [
      {
        "name": "Security Check 1",
        "location": {"lat": 52.5230, "lon": 13.4010},
      },
  {
      "name": "Security Check 2",
      "location": {"lat": 52.5230, "lon": 13.4010},
  }
    ],
      "relations": [
      {
          "type": "SAME_TIME",
          "jobs": ["Security Check 1", "Security Check 2"],
          "enforceCompatibility": true
      }
      ]
  }
  ```
</CodeGroup>

<Warning>
  **Important Considerations:**

  * Compatibility violations result in hard constraints (infeasible solutions)
  * Only applies when `enforceCompatibility: true` on SAME\_TIME relations
  * Overly restrictive compatibility can lead to no feasible solutions
  * Always validate your compatibility configuration with test requests
</Warning>

## Best Practices

<Tip>
  When using job relations, consider these best practices:

  1. **Start Simple**: Begin with basic relations and add complexity as needed
  2. **Avoid Over-constraining**: Too many relations can make the problem infeasible
  3. **Use Partial Planning**: Enable `partialPlanning` for relations that might be too restrictive
  4. **Test Incrementally**: Add relations one at a time to identify conflicts
  5. **Monitor Performance**: Complex relations can increase solve time
  6. **Resource Compatibility**: When using `enforceCompatibility`, ensure resources have properly configured `compatibleResources` lists
  7. **Validate Compatibility**: Test your compatibility configuration with sample requests before production use
</Tip>

## Troubleshooting

<Warning>
  Common issues when using job relations:

  * **Infeasible Solutions**: Too many conflicting relations
  * **Long Solve Times**: Complex relation networks require more computation
  * **Unexpected Results**: Relations might interact in non-obvious ways
</Warning>

<Info>
  Use the `/v2/vrp/jobs/{id}/explanation` endpoint to understand why certain relations couldn't be satisfied in your solution.
</Info>

## Related Features

* [Time Windows](/guides/vrp/features/window) - Combine with relations for complex scheduling
* [Multi-Day Planning](/guides/vrp/features/time-scheduling-advanced) - Use SAME\_DAY and SAME\_RESOURCE across days
* [Capacities](/guides/vrp/features/capacity-management) - Relations respect capacity constraints
* [Resources](/guides/vrp/features/resources) - Configure resource compatibility for team-based operations
