Docs
  • Solver
  • Models
    • Field Service Routing
    • Employee Shift Scheduling
    • Pick-up and Delivery Routing
    • Task Scheduling
  • Platform
Try models
  • Task Scheduling
  • Job service constraints
  • Time windows

Task Scheduling

    • Introduction
    • Getting started: Hello world
    • User guide
      • Terminology
      • Scheduling API concepts
      • Integration
      • Constraints
      • Using the API
        • Using the OpenAPI spec
        • API tooling
      • Demo datasets
      • Input datasets
        • Model configuration
        • Model input
      • Output datasets
        • Metadata
        • Model output
        • Input metrics
        • Key performance indicators (KPIs)
      • Job types and machine types
      • Resource-specific durations
      • Freeze jobs until
      • Metrics and optimization goals
      • Score analysis
      • Validation
    • Machine and employee resource constraints
      • Machine unavailability
      • Resource transitions
      • Employee resources
    • Job service constraints
      • Time windows
      • Time management
      • Job dependencies
      • Priority jobs
      • Tags and specific resources
    • Real-time planning
    • Changelog
    • Upgrading to the latest versions
    • Feature requests

Time windows

Time windows define when a job can be processed. In task scheduling, time windows let you control the earliest time a job can start and the latest time it can start or end.

These constraints are useful when work depends on upstream availability, operating hours, handoff deadlines, or delivery commitments. For example, a job may not be able to start before materials arrive, and it may need to complete before a shipping cutoff.

Choosing the right time windows is a balance. If windows are too narrow, the schedule has less flexibility and more jobs may remain unassigned. If windows are too broad, operational commitments are less precise and jobs may be planned much earlier or later than preferred.

This guide explains how to model job time windows and how each time-window constraint affects the resulting schedule.

  • Defining time windows
  • Required earliest start time
  • Required latest end time

Defining time windows

Learn how to configure an API Key to run the examples in this guide:
  1. Log in to Timefold Platform: app.timefold.ai

  2. From the Dashboard, click your tenant, and from the drop-down menu select Manage tenant, 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 Task Scheduling model.

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

Each job can define one or more time-window fields that control when it may be scheduled.

{
  "jobs": [
    {
      "id": "Job A",
      "duration": "PT2H",
      "minStart": "2027-02-01T10:00:00Z",
      "maxEnd": "2027-02-01T17:00:00Z"
    }
  ]
}
  • id is the job’s unique identifier.

  • duration is the amount of time it takes to complete the job. Duration uses ISO 8601 duration format.

  • minStart is the earliest time a job can start.

  • maxEnd is the latest time a job can end.

minStart and maxEnd use ISO 8601 date and time format with offset to UTC format.

Time windows are optional and can be combined:

  • If no time-window fields are provided, the job can be scheduled at any valid time.

  • If only minStart is provided, the job can start at or after that time.

  • If only maxEnd is provided, the job must finish at or before that time.

  • If multiple fields are provided, all defined limits apply together.

Required earliest start time

The Job started before minimum start hard constraint is invoked when a job includes a minStart time window field and the job is scheduled to start before that time.

The constraint adds a hard penalty to the dataset score relative to how many minutes before minStart the job was scheduled to start.

Jobs will be left unassigned if assigning them breaks this constraint.

Required earliest start time example

In the following example, there is one machine and one job with a required earliest start time of 10:00. The job has a duration of two hours, and the machine is available starting at 8:00.

The job is scheduled to start at 10:00, which is the earliest time it can start without breaking the Job started before minimum start constraint.

Job scheduled to start at the minimum start time
Figure 1. Job scheduled to start at the minimum start time
  • 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/job-scheduling/v1/schedules [email protected]
{
  "config": {
    "run": {
      "name": "Wait for minimum start"
    }
  },
  "modelInput": {
    "machines": [
      {
        "id": "Machine 1",
        "start": "2027-02-01T08:00:00Z"
      }
    ],
    "jobs": [
      {
        "id": "Job A",
        "duration": "PT2H",
        "minStart": "2027-02-01T10:00:00Z"
      }
    ]
  }
}
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/job-scheduling/v1/schedules/<ID>
{
  "metadata": {
    "id": "ID",
    "originId": "ID",
    "name": "Wait for minimum start",
    "submitDateTime": "2026-05-01T04:52:35.645318732Z",
    "startDateTime": "2026-05-01T04:53:25.499358964Z",
    "activeDateTime": "2026-05-01T04:53:25.711586394Z",
    "completeDateTime": "2026-05-01T04:53:27.25908694Z",
    "shutdownDateTime": "2026-05-01T04:53:27.567065041Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-240soft",
    "tags": [
      "system.type:from-request",
      "system.profile:default"
    ],
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "machines": [
      {
        "id": "Machine 1",
        "schedule": [
          {
            "id": "Job A",
            "start": "2027-02-01T10:00:00Z",
            "end": "2027-02-01T12:00:00Z"
          }
        ]
      }
    ]
  },
  "inputMetrics": {
    "jobs": 1,
    "machines": 1,
    "employees": 0
  },
  "kpis": {
    "makespan": "PT4H",
    "unassignedJobs": 0,
    "assignedJobs": 1,
    "activatedMachines": 1,
    "activatedEmployees": 0,
    "idealEndTimeDeviation": "PT0S"
  },
  "run": {
    "id": "ID",
    "originId": "ID",
    "name": "Wait for minimum start",
    "submitDateTime": "2026-05-01T04:52:35.645318732Z",
    "startDateTime": "2026-05-01T04:53:25.499358964Z",
    "activeDateTime": "2026-05-01T04:53:25.711586394Z",
    "completeDateTime": "2026-05-01T04:53:27.25908694Z",
    "shutdownDateTime": "2026-05-01T04:53:27.567065041Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-240soft",
    "tags": [
      "system.type:from-request",
      "system.profile:default"
    ],
    "validationResult": {
      "summary": "OK"
    }
  }
}

Required latest end time

The Job finished after maximum end hard constraint is invoked when a job includes a maxEnd time window field and the job is scheduled to end after that time. The constraint adds a hard penalty to the dataset score relative to how many minutes after maxEnd the job was scheduled to end.

Jobs will be left unassigned if assigning them breaks this constraint.

Required latest end time example

In the following example, there is one machine and two jobs, Job A and Job B. Job A has a duration of four hours and no time windows, so it can be scheduled at any time. Job B has a duration of two hours and a maxEnd time window of 11:00.

Job scheduled to finish at the maximum end time
Figure 2. Job scheduled to finish at the maximum end time
  • 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/job-scheduling/v1/schedules [email protected]
{
  "config": {
    "run": {
      "name": "Finish before maximum end"
    }
  },
  "modelInput": {
    "machines": [
      {
        "id": "Machine 1",
        "start": "2027-02-01T08:00:00Z"
      }
    ],
    "jobs": [
      {
        "id": "Job A",
        "duration": "PT4H"
      },
      {
        "id": "Job B",
        "duration": "PT2H",
        "maxEnd": "2027-02-01T11:00:00Z"
      }
    ]
  }
}
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/job-scheduling/v1/schedules/<ID>
{
  "metadata": {
    "id": "ID",
    "originId": "ID",
    "name": "Finish before maximum end",
    "submitDateTime": "2026-05-12T05:15:51.115920296Z",
    "startDateTime": "2026-05-12T05:16:05.800614739Z",
    "activeDateTime": "2026-05-12T05:16:05.937842996Z",
    "completeDateTime": "2026-05-12T05:16:36.328362105Z",
    "shutdownDateTime": "2026-05-12T05:16:36.328368195Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-360soft",
    "tags": [
      "system.type:from-request",
      "system.profile:Standard profile"
    ],
    "validationResult": {
      "summary": "OK"
    }
  },
  "modelOutput": {
    "machines": [
      {
        "id": "Machine 1",
        "schedule": [
          {
            "id": "Job B",
            "start": "2027-02-01T08:00:00Z",
            "end": "2027-02-01T10:00:00Z"
          },
          {
            "id": "Job A",
            "start": "2027-02-01T10:00:00Z",
            "end": "2027-02-01T14:00:00Z"
          }
        ]
      }
    ]
  },
  "inputMetrics": {
    "jobs": 2,
    "machines": 1,
    "employees": 0
  },
  "kpis": {
    "makespan": "PT6H",
    "unassignedJobs": 0,
    "assignedJobs": 2,
    "activatedMachines": 1,
    "activatedEmployees": 0,
    "idealEndTimeDeviation": "PT0S"
  },
  "run": {
    "id": "ID",
    "originId": "ID",
    "name": "Finish before maximum end",
    "submitDateTime": "2026-05-12T05:15:51.115920296Z",
    "startDateTime": "2026-05-12T05:16:05.800614739Z",
    "activeDateTime": "2026-05-12T05:16:05.937842996Z",
    "completeDateTime": "2026-05-12T05:16:36.328362105Z",
    "shutdownDateTime": "2026-05-12T05:16:36.328368195Z",
    "solverStatus": "SOLVING_COMPLETED",
    "score": "0hard/0medium/-360soft",
    "tags": [
      "system.type:from-request",
      "system.profile:Standard profile"
    ],
    "validationResult": {
      "summary": "OK"
    }
  }
}

Next

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

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