[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/api/engine-schedule/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Engine.Schedule

Schedules a [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>) snapshot once and returns the result. The call is stateless: it runs `new Project().Solve(data, options)` on a temporary [`Project`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/project.md>) that's discarded when the call returns. Nothing is kept between calls. To keep the schedule and send edits to it, use [`Project.Solve`](<https://docs.dhtmlx.com/planning-engine/net/api/project-solve.md>).

## Signature

```csharp
public static ScheduleResult Schedule(ProjectData data, SolveOptions options)
```

A static method of the static class `Engine`. Synchronous and CPU-only. The same `data` and `options` always produce the same result.

## Parameters

| Name | Type | Description |
|---|---|---|
| `data` | [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>) | The full snapshot to schedule |
| `options` | [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/solve-options.md>) | What to schedule and what to report. `new SolveOptions()` schedules the whole project. |

## Behavior

- The call deep-copies `data` before scheduling, so the caller's [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>) never changes.
- The call always validates `data` with [`Validation.Strict`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/validation.md>). It rejects invalid data and never repairs it.

## Returns

A new [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>). No project holds a reference to it, so the caller can modify it freely.

The result's `BaselineId` is set, but it names the baseline of the temporary project, so no later call can use it.

## Errors

| Error | When |
|---|---|
| [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>) | `data` fails strict validation, or `options.Subtree` names an unknown or unscheduled task. The validation rules are listed on [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/net/api/core/data/project-data.md>). |
| `ArgumentNullException` | `data` or `options` is `null` |

`Schedule` never throws [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>): each call starts from a fresh project.

## Example

```csharp
using Plen;

var monday = Moment.FromYmdHm(2026, 8, 10, 8, 0) ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Tasks =
    [
        new TaskData("design") { StartDate = monday, Duration = 2.0 },
        new TaskData("build") { StartDate = monday, Duration = 3.0 },
    ],
    Links = [new LinkData { Id = "l1", Source = "design", Target = "build" }],
};

var result = Engine.Schedule(data, new SolveOptions());

foreach (var update in result.Updates)
    Console.WriteLine($"{update.Id}: {update.StartDate} .. {update.EndDate}");
```

## Related

- [`Project.Solve`](<https://docs.dhtmlx.com/planning-engine/net/api/project-solve.md>) - the stateful call that keeps the schedule
- [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/solve-options.md>) - the options
- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>) - the returned result
- [Scheduling a project](<https://docs.dhtmlx.com/planning-engine/net/scheduling/scheduling-a-project.md>) - loading, caching and solve options
- [Reading results](<https://docs.dhtmlx.com/planning-engine/net/scheduling/reading-results.md>) - writing updates back and handling each diagnostic
