Docs
  • Solver
  • Models
    • Field Service Routing
    • Employee Shift Scheduling
  • Platform
Try models
  • Field Service Routing
  • Real-time planning
  • Real-time planning: no show

Field Service Routing

    • Introduction
    • Planning AI concepts
    • Metrics and optimization goals
    • Getting started with field service routing
    • Understanding the API
    • Constraints
    • Vehicle resource constraints
      • Shift hours and overtime
      • Lunch breaks and personal appointments
      • Fairness
      • Technician costs
    • Visit service constraints
      • Time windows and opening hours
      • Skills
      • Visit dependencies
      • Visit requirements
      • Multi-vehicle visits
      • Priority visits and optional visits
    • Real-time planning
      • Real-time planning
      • Real-time planning: extended visit
      • Real-time planning: reassignment
      • Real-time planning: emergency visit
      • Real-time planning: no show
      • Real-time planning: technician ill
      • Real-time planning: pinning visits
    • Recommendations
      • Recommendations
      • Visit time window recommendations
      • Visit group time window recommendations
    • Time zones and daylight-saving time (DST)
    • New and noteworthy
    • Upgrading to the latest versions
    • Feature requests
    • Reference guide

Real-time planning: no show

There are many situations where Real-time planning is necessary.

Sometimes customers are not available at the scheduled time.

When Carl arrives at his first visit of the day, the customer isn’t there to let him in. Carl lets head office know, and they start re-planning the visits for his shift.

Carl waits for 10 minutes at the customer location, but the customer doesn’t show up. The real-time plan is published and Carl goes to his next visit.

real time planning no show

Prerequisites

To run the examples in this guide, you need to authenticate with a valid API key for this model:

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

  2. From the Dashboard, click your tenant, and from the drop-down menu select Tenant Settings, then choose API Keys.

  3. Create a new API key or use an existing one. Ensure the list of models for the API key contains the current model.

In the examples, replace <API_KEY> with the API Key you just copied.

1. Batch schedule: no show

Carl’s original schedule was generated from the following input dataset during the regular batch scheduling:

  • Input

  • Output

Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/field-service-routing/v1/route-plans [email protected]
{
  "config": {
    "run": {
      "name": "Original shift plan: no show example"
    }
  },
  "modelInput": {
    "vehicles": [
      {
        "id": "Carl",
        "shifts": [
          {
            "id": "Carl-2027-02-01",
            "startLocation": [33.68786, -84.18487],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z"
          }
        ]
      }
    ],
    "visits": [
      {
        "id": "Visit E",
        "location": [33.84475, -84.63649],
        "serviceDuration": "PT1H"
      },
      {
        "id": "Visit B",
        "location": [33.90719, -84.28149],
        "serviceDuration": "PT1H"
      },
      {
        "id": "Visit D",
        "location":  [33.89351, -84.00649],
        "serviceDuration": "PT1H"
      }
    ]
  }
}
To request the solution, locate the ID from the response to the post operation and append it to the following API call:
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/field-service-routing/v1/route-plans/<ID>
{
  "run": {
    "id": "ID",
    "name": "Original shift plan: no show example",
    "submitDateTime": "2024-11-04T05:29:38.20548591Z",
    "startDateTime": "2024-11-04T05:29:43.999060017Z",
    "activeDateTime": "2024-11-04T05:29:44.099060017Z",
    "completeDateTime": "2024-11-04T05:34:44.363546854Z",
    "shutdownDateTime": "2024-11-04T05:34:44.463546854Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-174887soft",
    "tags": null,
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "vehicles": [
      {
        "id": "Carl",
        "shifts": [
          {
            "id": "Carl-2027-02-01",
            "startTime": "2027-02-01T09:00:00Z",
            "itinerary": [
              {
                "id": "Visit E",
                "kind": "VISIT",
                "arrivalTime": "2027-02-01T09:48:56Z",
                "startServiceTime": "2027-02-01T09:48:56Z",
                "departureTime": "2027-02-01T10:48:56Z",
                "effectiveServiceDuration": "PT1H",
                "travelTimeFromPreviousStandstill": "PT48M56S",
                "travelDistanceMetersFromPreviousStandstill": 54141,
                "minStartTravelTime": "2027-02-01T00:00:00Z"
              },
              {
                "id": "Visit B",
                "kind": "VISIT",
                "arrivalTime": "2027-02-01T11:29:29Z",
                "startServiceTime": "2027-02-01T11:29:29Z",
                "departureTime": "2027-02-01T12:29:29Z",
                "effectiveServiceDuration": "PT1H",
                "travelTimeFromPreviousStandstill": "PT40M33S",
                "travelDistanceMetersFromPreviousStandstill": 42302,
                "minStartTravelTime": "2027-02-01T00:00:00Z"
              },
              {
                "id": "Visit D",
                "kind": "VISIT",
                "arrivalTime": "2027-02-01T13:01:19Z",
                "startServiceTime": "2027-02-01T13:01:19Z",
                "departureTime": "2027-02-01T14:01:19Z",
                "effectiveServiceDuration": "PT1H",
                "travelTimeFromPreviousStandstill": "PT31M50S",
                "travelDistanceMetersFromPreviousStandstill": 34289,
                "minStartTravelTime": "2027-02-01T00:00:00Z"
              }
            ],
            "metrics": {
              "totalTravelTime": "PT2H39M10S",
              "travelTimeFromStartLocationToFirstVisit": "PT48M56S",
              "travelTimeBetweenVisits": "PT1H12M23S",
              "travelTimeFromLastVisitToEndLocation": "PT37M51S",
              "totalTravelDistanceMeters": 165337,
              "travelDistanceFromStartLocationToFirstVisitMeters": 54141,
              "travelDistanceBetweenVisitsMeters": 76591,
              "travelDistanceFromLastVisitToEndLocationMeters": 34605,
              "endLocationArrivalTime": "2027-02-01T14:39:10Z"
            }
          }
        ]
      }
    ]
  },
  "kpis": {
    "totalTravelTime": "PT2H39M10S",
    "travelTimeFromStartLocationToFirstVisit": "PT48M56S",
    "travelTimeBetweenVisits": "PT1H12M23S",
    "travelTimeFromLastVisitToEndLocation": "PT37M51S",
    "totalTravelDistanceMeters": 165337,
    "travelDistanceFromStartLocationToFirstVisitMeters": 54141,
    "travelDistanceBetweenVisitsMeters": 76591,
    "travelDistanceFromLastVisitToEndLocationMeters": 34605,
    "totalUnassignedVisits": 0
  }
}

modelOutput contains Carl’s shift itinerary.

2. Real-time planning update: no show

Carl reported the customer was not present when he arrived and waited at the visit location.

Update the serviceDuration for Visit E from 1 hour to 10 minutes.

The customer was not present and the work was not completed. Assuming the customer still wants the work completed, the visit will need to be rescheduled for a later time.

Add the minStartTravelTime from the most recent planning output dataset (batch or real-time) to each visit:

{
  "visits": [
    {
      "id": "Visit E",
      "location": [33.84475, -84.63649],
      "serviceDuration": "PT10M",
      "minStartTravelTime": "2027-02-01T00:00:00Z"
    },
    {
      "id": "Visit B",
      "location": [33.90719, -84.28149],
      "serviceDuration": "PT1H",
      "minStartTravelTime": "2027-02-01T00:00:00Z"
    },
    {
      "id": "Visit D",
      "location":  [33.89351, -84.00649],
      "serviceDuration": "PT1H",
      "minStartTravelTime": "2027-02-01T00:00:00Z"
    }
  ]
}

Add the itinerary to Carl’s shifts with Visit E, Visit B, and Visit D, including the visit IDs and the visit kind:

{
  "id": "Carl",
  "shifts": [
    {
      "id": "Carl-2027-02-01",
      "startLocation": [33.68786, -84.18487],
      "minStartTime": "2027-02-01T09:00:00Z",
      "maxEndTime": "2027-02-01T17:00:00Z",
      "itinerary": [
        {
          "id": "Visit E",
          "kind": "VISIT"
        },
        {
          "id": "Visit B",
          "kind": "VISIT"
        },
        {
          "id": "Visit D",
          "kind": "VISIT"
        }
      ]
    }
  ]
}

Freeze the departure times for visits that have already occurred and that technicians have begun traveling to by adding freezeDeparturesBeforeTime:

{
  "modelInput": {
    "freezeDeparturesBeforeTime": "2027-02-01T10:00:00Z"
  }
}

Carl arrived at Visit E at 09:48 and waited 10 minutes. FreezeDeparturesBeforeTime is set to 10:00 so that his next visits can be rescheduled, and he can travel to the next location.

Submit the updated input dataset to generate the new real-time plan.

  • Input

  • Output

Try this example in Timefold Platform by saving this JSON into a file called sample.json and make the following API call:
curl -X POST -H "Content-type: application/json" -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/field-service-routing/v1/route-plans [email protected]
{
  "config": {
    "run": {
      "name": "Real-time planning: no show example"
    }
  },
  "modelInput": {
    "freezeDeparturesBeforeTime": "2027-02-01T10:00:00Z",
    "vehicles": [
      {
        "id": "Carl",
        "shifts": [
          {
            "id": "Carl-2027-02-01",
            "startLocation": [33.68786, -84.18487],
            "minStartTime": "2027-02-01T09:00:00Z",
            "maxEndTime": "2027-02-01T17:00:00Z",
            "itinerary": [
              {
                "id": "Visit E",
                "kind": "VISIT"
              },
              {
                "id": "Visit B",
                "kind": "VISIT"
              },
              {
                "id": "Visit D",
                "kind": "VISIT"
              }
            ]
          }
        ]
      }
    ],
    "visits": [
      {
        "id": "Visit E",
        "location": [33.84475, -84.63649],
        "serviceDuration": "PT10M"
      },
      {
        "id": "Visit B",
        "location": [33.90719, -84.28149],
        "serviceDuration": "PT1H"
      },
      {
        "id": "Visit D",
        "location":  [33.89351, -84.00649],
        "serviceDuration": "PT1H"
      }
    ]
  }
}
To request the solution, locate the ID from the response to the post operation and append it to the following API call:
curl -X GET -H 'X-API-KEY: <API_KEY>' https://app.timefold.ai/api/models/field-service-routing/v1/route-plans/<ID>
{
  "run": {
    "id": "ID",
    "name": "Real-time planning: no show example",
    "submitDateTime": "2024-11-04T05:40:45.659685234Z",
    "startDateTime": "2024-11-04T05:40:51.478014538Z",
    "activeDateTime": "2024-11-04T05:40:51.578014538Z",
    "completeDateTime": "2024-11-04T05:43:03.769027588Z",
    "shutdownDateTime": "2024-11-04T05:43:03.869027588Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-174887soft",
    "tags": null,
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "vehicles": [
      {
        "id": "Carl",
        "shifts": [
          {
            "id": "Carl-2027-02-01",
            "startTime": "2027-02-01T09:00:00Z",
            "itinerary": [
              {
                "id": "Visit E",
                "kind": "VISIT",
                "arrivalTime": "2027-02-01T09:48:56Z",
                "startServiceTime": "2027-02-01T09:48:56Z",
                "departureTime": "2027-02-01T09:58:56Z",
                "effectiveServiceDuration": "PT10M",
                "travelTimeFromPreviousStandstill": "PT48M56S",
                "travelDistanceMetersFromPreviousStandstill": 54141,
                "minStartTravelTime": "2027-02-01T00:00:00Z"
              },
              {
                "id": "Visit B",
                "kind": "VISIT",
                "arrivalTime": "2027-02-01T10:39:29Z",
                "startServiceTime": "2027-02-01T10:39:29Z",
                "departureTime": "2027-02-01T11:39:29Z",
                "effectiveServiceDuration": "PT1H",
                "travelTimeFromPreviousStandstill": "PT40M33S",
                "travelDistanceMetersFromPreviousStandstill": 42302,
                "minStartTravelTime": "2027-02-01T00:00:00Z"
              },
              {
                "id": "Visit D",
                "kind": "VISIT",
                "arrivalTime": "2027-02-01T12:11:19Z",
                "startServiceTime": "2027-02-01T12:11:19Z",
                "departureTime": "2027-02-01T13:11:19Z",
                "effectiveServiceDuration": "PT1H",
                "travelTimeFromPreviousStandstill": "PT31M50S",
                "travelDistanceMetersFromPreviousStandstill": 34289,
                "minStartTravelTime": "2027-02-01T10:00:00Z"
              }
            ],
            "metrics": {
              "totalTravelTime": "PT2H39M10S",
              "travelTimeFromStartLocationToFirstVisit": "PT48M56S",
              "travelTimeBetweenVisits": "PT1H12M23S",
              "travelTimeFromLastVisitToEndLocation": "PT37M51S",
              "totalTravelDistanceMeters": 165337,
              "travelDistanceFromStartLocationToFirstVisitMeters": 54141,
              "travelDistanceBetweenVisitsMeters": 76591,
              "travelDistanceFromLastVisitToEndLocationMeters": 34605,
              "endLocationArrivalTime": "2027-02-01T13:49:10Z"
            }
          }
        ]
      }
    ]
  },
  "kpis": {
    "totalTravelTime": "PT2H39M10S",
    "travelTimeFromStartLocationToFirstVisit": "PT48M56S",
    "travelTimeBetweenVisits": "PT1H12M23S",
    "travelTimeFromLastVisitToEndLocation": "PT37M51S",
    "totalTravelDistanceMeters": 165337,
    "travelDistanceFromStartLocationToFirstVisitMeters": 54141,
    "travelDistanceBetweenVisitsMeters": 76591,
    "travelDistanceFromLastVisitToEndLocationMeters": 34605,
    "totalUnassignedVisits": 0
  }
}

modelOutput contains Carl’s updated shift itinerary.

Visit E was a no show, so Visits B and D are rescheduled for earlier in the day.

Next

  • Understand the constraints of the Field Service Routing model.

  • See the full API spec or try the online API.

  • Manage shift times with Time zones and daylight-saving time (DST) changes.

  • Learn about real-time planning.

  • Real-time planning with pinned visits.

  • Real-time planning with extended visits.

  • Real-time planning and emergency visits.

  • © 2025 Timefold BV
  • Timefold.ai
  • Documentation
  • Changelog
  • Send feedback
  • Privacy
  • Legal
    • Light mode
    • Dark mode
    • System default