Getting started with field service routing

This guide introduces Timefold’s Field Service Routing model and walks you through the steps to use Timefold Platform to create an optimized field service routing itinerary.

The steps in this guide can be completed in under 10 minutes.

1. Field service routing hello world example

This hello world uses an example with one vehicle and one visit to demonstrate the process of requesting and retrieving a solution from Timefold’s field service routing model.

In the example, Ann works as a technician for a telecom company and drives between locations to connect people’s homes to the internet.

1.1. Prerequisites

To follow this guide, you need:

  • An active Timefold account

  • An API client (optional but recommended)

1.2. The data set

A data set for the Field Service Routing model must include information about your customers' requests and your technicians' availability. For instance, customers who require an internet connection at their homes, and service technicians who can visit those customers and install the necessary equipment.

Requests can also include when customers are available to let the technician in, the required skills necessary to complete the visit, and requirements for the technician, for instance, required breaks, how many technicians are required to complete the work, and the skill level of the technicians, to name a few.

You create your data set using our predefined model schema which follows the OpenAPI specification. The modelInput object contains the data set to be optimized, which, at a minimum, must include vehicles and visits:

minimum-data-set-input.json
{
  "modelInput": {
    "vehicles": [
      {
        "id": "Ann",
        "shifts": [
          {
            "id": "Ann-2027-2-1",
            "startLocation": [33.68786, -84.18487],
            "minStartTime": "2027-02-01T09:00:00Z"
          }
        ]
      }
    ],
    "visits": [
      {
        "id": "Visit A",
        "location": [33.77301, -84.43838],
        "serviceDuration": "PT1H30M"
      }
    ]
  }
}
Copy this example data set into a file called sample.json to use in this hello world example.

1.2.1. Vehicles

In this example, there is one vehicle. vehicles includes id and shifts.

"vehicles": [
  {
    "id": "Ann",
    "shifts": [
      {
        "id": "Ann-2027-2-1",
        "startLocation": [33.68786, -84.18487],
        "minStartTime": "2027-02-01T09:00:00Z"
      }
    ]
  }
],

id identifies the vehicle. In this case, the id has the value "Ann" to identify this as Ann’s vehicle.

shifts represents a period of time the vehicle and its crew is working, typically a day shift. For example, 1-Feb from 09:00 to 17:00. shifts includes an id, startLocation, and minStartTime.

id identifies one shift (one day) worked in this vehicle. Ann works this shift, and the string "Ann-2027-2-1" identifies this specific shift.

startLocation provides Ann’s location at the start of the shift. This is the location she travels from when she leaves for the first visit.

minStartTime sets the earliest time Ann can start her shift.

1.2.2. Visits

In this example, there is one customer who requires an internet connection at their home. The visits object includes information about the customer’s location:

"visits": [
  {
    "id": "Visit A",
    "location": [33.77301, -84.43838],
    "serviceDuration": "PT1H30M"
  }
]

id identifies the visit. In this case, id has the value "Visit A", but you could use a customer identifier from your CRM or another meaningful identifier.

location provides the location of the visit. This is the customer’s home that needs a connection to the internet.

serviceDuration is the estimated duration of the visit. serviceDuration uses the ISO 8601 duration format. The value "PT1H30M" indicates the estimated duration is 1 hour and 30 minutes.

1.3. Post the data set

Post the data set in the Timefold Platform UI

Typically, you post the data set to the API. However, for testing purposes, you can upload your sample.json directly in the platform UI.

  1. Log into the Timefold dashboard: https://app.timefold.ai

  2. From the Field Service Routing tile, select Run model.

  3. Click New run.

  4. Upload the sample.json file you saved earlier.

  5. Click Schedule run.

  6. Navigate to the Output section to see the completed route

To authenticate with the Timefold API you need an API key.

  1. Log in to Timefold Platform: app.timefold.ai

  2. From the Dashboard, click your username, and from the drop-down menu select API Keys.

  3. Copy the default API key.

Request the solution for your data set by posting the sample.json file to the API endpoint /v1/route-plans.

Replace <your-api-key> with the API key you just copied.
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <your-api-key>' https://app.timefold.ai/api/models/field-service-routing/v1/route-plans [email protected]

1.4. Output from the request

The output to the API request follows:

minimum-data-set-output.json
{
    "id": <unique-id>,
    "name": <unique-name>,
    "submitDateTime": "2024-07-05T07:27:28.178351918Z",
    "startDateTime": null,
    "completeDateTime": null,
    "solverStatus": "SOLVING_SCHEDULED",
    "score": null,
    "tags": null,
    "validationResult": null
}

The output includes an id and name that have been assigned to identify the run associated with the data set. You’ll use this id to retrieve the results. Later, you’ll use name to locate more information in Timefold Platform.

solverStatus confirms the data set has been scheduled for solving.

1.5. Request the solution

Append the id to the API endpoint /v1/route-plans and create a GET request to retrieve the solution:

curl -X GET -H 'X-API-KEY: <your-api-key>' https://app.timefold.ai/api/models/field-service-routing/v1/route-plans/<unique-id>

1.5.1. Completed route

completed-route.json
{
    "run": {
        "id": <unique-id>,
        "name": <unique-name>,
        "submitDateTime": "2024-07-05T07:27:28.178351918Z",
        "startDateTime": "2024-07-05T07:27:32.349292848Z",
        "completeDateTime": "2024-07-05T07:27:34.435404549Z",
        "solverStatus": "SOLVING_COMPLETED",
        "score": "0hard/0medium/-3569soft",
        "tags": null,
        "validationResult": {
            "summary": "OK"
        }
    },
    "modelOutput": {
        "vehicles": [
            {
                "id": "Ann",
                "shifts": [
                    {
                        "id": "Ann-2027-2-1",
                        "startTime": "2027-02-01T09:00:00Z",
                        "itinerary": [
                            {
                                "id": "Visit A",
                                "kind": "VISIT",
                                "arrivalTime": "2027-02-01T09:29:57Z",
                                "startServiceTime": "2027-02-01T09:29:57Z",
                                "departureTime": "2027-02-01T10:59:57Z",
                                "effectiveServiceDuration": "PT1H30M",
                                "travelTimeFromPreviousStandstill": "PT29M57S",
                                "travelDistanceMetersFromPreviousStandstill": 31492,
                                "minStartTravelTime": "2027-02-01T00:00:00Z"
                            }
                        ],
                        "metrics": {
                            "totalTravelTime": "PT59M29S",
                            "travelTimeFromStartLocationToFirstVisit": "PT29M57S",
                            "travelTimeBetweenVisits": "PT0S",
                            "travelTimeFromLastVisitToEndLocation": "PT29M32S",
                            "totalTravelDistanceMeters": 65476,
                            "travelDistanceFromStartLocationToFirstVisitMeters": 31492,
                            "travelDistanceBetweenVisitsMeters": 0,
                            "travelDistanceFromLastVisitToEndLocationMeters": 33984,
                            "endLocationArrivalTime": "2027-02-01T11:29:29Z"
                        }
                    }
                ]
            }
        ]
    },
    "kpis": {
        "totalTravelTime": "PT59M29S",
        "travelTimeFromStartLocationToFirstVisit": "PT29M57S",
        "travelTimeBetweenVisits": "PT0S",
        "travelTimeFromLastVisitToEndLocation": "PT29M32S",
        "totalTravelDistanceMeters": 65476,
        "travelDistanceFromStartLocationToFirstVisitMeters": 31492,
        "travelDistanceBetweenVisitsMeters": 0,
        "travelDistanceFromLastVisitToEndLocationMeters": 33984,
        "totalUnassignedVisits": 0
    }
}

The output shows the solverStatus is SOLVING COMPLETED.

modelOutput contains the solution for the data set.

"itinerary": [
    {
        "id": "Visit A",
        "kind": "VISIT",
        "arrivalTime": "2027-02-01T09:29:57Z",
        "startServiceTime": "2027-02-01T09:29:57Z",
        "departureTime": "2027-02-01T10:59:57Z",
        "effectiveServiceDuration": "PT1H30M",
        "travelTimeFromPreviousStandstill": "PT29M57S",
        "travelDistanceMetersFromPreviousStandstill": 31492,
        "minStartTravelTime": "2027-02-01T00:00:00Z"
    }
],

itinerary includes the details for Ann’s schedule, including when she arrives at the customer’s location to connect their home to the internet.

arrivalTime at the visit and startServiceTime are both 2027-02-01T09:29:57Z, or 9:29 on February 1, 2027. The effectiveServiceDuration is 1 hour and 30 minutes ("PT1H30M"), and the departureTime is "2027-02-01T10:59:57Z" or 10:59.

Ann’s schedule for her shift is below. Travel time is marked in orange on the timeline, and Visit A is marked in green.

Field Service Routing time view

Beyond hello world

This example walked you through creating a simple data set to create a schedule for one vehicle to travel to one visit. Timefold optimizes routes for thousands of technicians automatically and incorporates constraints for skill requirements, shift limits, and more.

Configure a webhook

In this getting started guide, you learned how to retrieve the solution for your data set through the API and Timefold Platform. However, you can configure a webhook to receive the solution without the need to poll Timefold’s API.

To configure a webhook:

  1. Log in to Timefold Platform app.timefold.ai

  2. From the Dashboard, click your username, from the drop-down menu select Webhooks.

  3. Click New webhook.

  4. Give your webhook a name.

  5. Enter the URL for your webhook.

  6. Enable the webhook and click Add webhook.

Next

  • Learn about the constraints of the field service routing model.