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


# SchedulingChanges

A set of edits to a [`JsonProject`](<https://docs.dhtmlx.com/planning-engine/wasm/api/json-project.md>): tasks, links, resources and assignments to add, update or remove, plus an optional baseline check. Send it as `changes_json` to [`apply`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md>) or [`preview`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-preview.md>), or as `changes` of a candidate passed to [`evaluate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-evaluate.md>). [`suggestAssignments`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-suggest-assignments.md>) returns one as `changes`.

```ts
type SchedulingChanges = {
  baselineId?: string;
  tasks?: { add?: TaskData[]; update?: TaskUpdate[]; remove?: Id[] };
  links?: { add?: LinkAdd[]; update?: LinkUpdate[]; remove?: Id[] };
  resources?: { add?: ResourceData[]; update?: ResourceUpdate[]; remove?: Id[] };
  assignments?: { add?: AssignmentData[]; update?: AssignmentUpdate[]; remove?: Id[] };
};
```

## Fields

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `baselineId` | `string` \| `null` | no | absent | Baseline token the edits were made against. Absent or `null` skips the check. A token that doesn't name the project's current baseline fails the whole call with `kind: "project"`, `code: "stale-baseline"`, before any operation runs. |
| `tasks` | [bucket](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#buckets>) of [`TaskData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/task-data.md>) / [`TaskUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/task-update.md>) \| `null` | no | empty | Tasks to add, update or remove. |
| `links` | [bucket](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#buckets>) of [`LinkAdd`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#linkadd>) / [`LinkUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#linkupdate>) \| `null` | no | empty | Links to add, update or remove. |
| `resources` | [bucket](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#buckets>) of [`ResourceData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#resourcedata>) / [`ResourceUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#resourceupdate>) \| `null` | no | empty | Resources to add, update or remove. |
| `assignments` | [bucket](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#buckets>) of [`AssignmentData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/assignment-data.md>) / [`AssignmentUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#assignmentupdate>) \| `null` | no | empty | Assignments to add, update or remove. |

The field is spelled `baselineId`. Take the token from the latest result that carries one, such as the [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/schedule-result.md>) of a `solve`.

There's no `calendars` field. Calendars can't be added or edited through a change set; that takes [`solve`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-solve.md>) with full data. Updates can still point tasks and resources at existing calendars through `calendar_id`.

The change set and its buckets reject unknown fields: `{"tasks": {"rename": []}}` fails the whole call with `parse`. The records inside `add` and `update` ignore unknown fields. See [Wire format](<https://docs.dhtmlx.com/planning-engine/wasm/wire-format.md#input-unknown-fields>).

:::note
A `priority` outside 0..1000 or a malformed hour range fails the whole call with a `validation` error that has no `path`. In `apply`, this means no operation from that change set is applied.
:::

## Buckets

Each of `tasks`, `links`, `resources` and `assignments` is an object with up to three lists. Any list can be omitted.

| Field | Type | Description |
|---|---|---|
| `add` | record array | New records. |
| `update` | update array | Edits to existing records, each naming its record by `id`. In an update, an omitted field stays unchanged and `null` clears it; see [Wire format](<https://docs.dhtmlx.com/planning-engine/wasm/wire-format.md#input-omitted-and-null>). |
| `remove` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>)`[]` | Ids of records to remove. |

When present, each list must be an array; `null` there is a `parse` error.

| Bucket | `add` | `update` | `remove` |
|---|---|---|---|
| `tasks` | [`TaskData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/task-data.md>) | [`TaskUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/task-update.md>) | task ids |
| `links` | [`LinkAdd`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#linkadd>) | [`LinkUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#linkupdate>) | link ids |
| `resources` | [`ResourceData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#resourcedata>) | [`ResourceUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#resourceupdate>) | resource ids |
| `assignments` | [`AssignmentData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/assignment-data.md>) | [`AssignmentUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/scheduling-changes.md#assignmentupdate>) | assignment ids |

Every list entry is one operation, named by its path: `tasks.update[0]`, `links.remove[2]`. [`ApplyReport`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md#applyreport>) lists accepted and rejected operations by these paths.

Removing a task also removes its descendants and the links and assignments that use them. Removing a resource also removes its assignments. The removed ids are listed in [`ChangeEffects`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md#changeeffects>).

## Operation order

Operations run in a fixed order, not in the order the fields appear in the JSON. Buckets run in the order `tasks`, `links`, `resources`, `assignments`. Within a bucket:

| Bucket | Order |
|---|---|
| `tasks` | `remove`, `add`, `update` |
| `links` | `remove`, `update`, `add` |
| `resources` | `remove`, `add`, `update` |
| `assignments` | `remove`, `update`, `add` |

Entries of one list run in array order. Because removals run first, an `add` can reuse an id removed in the same change set, and links and assignments can refer to tasks and resources added in it.

## Rejected operations

A malformed change set, such as a missing required field or a wrong JSON type, fails the whole call. An operation that decodes but doesn't fit the project is rejected on its own and listed in `rejected` of the [`ApplyReport`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md#applyreport>):

| Operation | Rejected when |
|---|---|
| any `remove` | No record of that kind has the id (`unknown task id`, `unknown link id`, ...). |
| any `update` | No record of that kind has the `id`. |
| any `add` | The id is already used by a record of that kind (`duplicate task id`, ...). |
| any `add` / `update` | The resulting record fails the same validation as project data, such as an unknown `calendar_id`. |
| `links.update`, `assignments.update` | A required field (`source`, `target`, `task`, `resource`, `value`) is set to `null`. |

## LinkAdd

A new link in `links.add`. The fields mean the same as on [`LinkData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/link-data.md>), except that `id` is optional. Unknown fields are ignored.

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) \| `null` | no | generated | Id of the new link. Omitted or `null`: the first free id of the form `$generated_link_1`, `$generated_link_2`, and so on. Generated ids are listed in `generatedLinks` of [`ChangeEffects`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md#changeeffects>). |
| `source` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | yes | - | Id of the predecessor task. |
| `target` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | yes | - | Id of the successor task. |
| `type` | `string` \| `number` \| `null`, see [link type](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#link-type>e) | no | `"fs"` | `"fs"`, `"ss"`, `"ff"` or `"sf"`; also `0`-`3` and `"0"`-`"3"`. `null` reads as `"fs"`. |
| `lag` | `number` \| `null` | no | `0` | Working time between the two ends, in `lag_unit`. `null` reads as `0`. |
| `lag_unit` | [`TimeUnit`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#timeunit>) \| `null` | no | `config.duration_unit` | `"minute"`, `"hour"` or `"day"`. |

An endpoint that names no task, or an unscheduled task, doesn't reject the operation. The link is added and listed in `droppedLinks` of [`ChangeEffects`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md#changeeffects>).

## LinkUpdate

An edit to one existing link in `links.update`. Unknown fields are ignored.

| Field | Type | Required | `null` | Description |
|---|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | yes | - | Id of the link to edit. The id itself can't change. |
| `source` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | no | rejected | New predecessor task. |
| `target` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | no | rejected | New successor task. |
| `type` | `string` \| `number`, see [link type](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#link-type>) | no | resets to `"fs"` | New link type. |
| `lag` | `number` | no | resets to `0` | New lag, in the link's lag unit. |
| `lag_unit` | [`TimeUnit`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#timeunit>) | no | clears it: `lag` is read in `config.duration_unit` | New unit of `lag` for this link. |

An omitted field stays unchanged. A new `source` or `target` that names no task, or an unscheduled task, doesn't reject the operation; the link is listed in `droppedLinks`.

## ResourceUpdate

An edit to one existing resource in `resources.update`. The fields mean the same as on [`ResourceData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#resourcedata>). Unknown fields are ignored.

| Field | Type | Required | `null` | Description |
|---|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | yes | - | Id of the resource to edit. |
| `capacity` | `number` | no | clears it: `config.default_resource_capacity` applies | New capacity. |
| `calendar_id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | no | clears it: the resource has no calendar of its own | New calendar. Must name a calendar already in the project. |

An omitted field stays unchanged. A calendar change can move the dates of tasks whose assignments work on that resource's calendar; see [Resources and assignments](<https://docs.dhtmlx.com/planning-engine/wasm/resources-and-assignment/resources-and-assignments.md>).

## AssignmentUpdate

An edit to one existing assignment in `assignments.update`. The fields mean the same as on [`AssignmentData`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/assignment-data.md>). Unknown fields are ignored.

| Field | Type | Required | `null` | Description |
|---|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | yes | - | Id of the assignment to edit. The id itself can't change. |
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | no | rejected | Moves the assignment to another task. `task_id` is accepted as an alias; when both are present, `task` wins. |
| `resource` | [`Id`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/common.md#id>) | no | rejected | Hands the assignment to another resource. `resource_id` is accepted as an alias; when both are present, `resource` wins. |
| `value` | `number` | no | rejected | New units booked. |
| `offset` | `number` | no | clears it: the slice starts at the task start | New start of the slice, as worked time from the task start. |
| `duration` | `number` | no | clears it: the slice runs to the task end | New worked time of the slice. |

An omitted field stays unchanged. Changes to `offset` and `duration` never move task dates.

## Used by

- [`JsonProject.apply`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md>): `changes_json`
- [`JsonProject.preview`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-preview.md>): `changes_json`
- [`JsonProject.evaluate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-evaluate.md>): `changes` of each candidate in `candidates_json`
- [`JsonProject.suggestAssignments`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-suggest-assignments.md>): `changes` of the result

## Example

Move one task, remove another, link two tasks and raise a resource's capacity, checked against the current baseline:

```json
{
  "baselineId": "1-b0605af8cba3d7c9",
  "tasks": {
    "update": [{ "id": "design", "start_date": "2026-08-12 08:00" }],
    "remove": ["draft"]
  },
  "links": {
    "add": [{ "source": "design", "target": "build", "type": "fs" }]
  },
  "resources": {
    "update": [{ "id": "team", "capacity": 2 }]
  },
  "assignments": {
    "update": [{ "id": "a1", "offset": null, "duration": 3 }]
  }
}
```

## Related

- [`ApplyReport`](<https://docs.dhtmlx.com/planning-engine/wasm/api/project-apply.md#applyreport>) - accepted and rejected operations
- [`TaskUpdate`](<https://docs.dhtmlx.com/planning-engine/wasm/api/types/task-update.md>) - task edits
- [Editing a Project](<https://docs.dhtmlx.com/planning-engine/wasm/live-projects/editing-a-project.md>) - change sets, applying and rescheduling
- [Previewing Changes](<https://docs.dhtmlx.com/planning-engine/wasm/live-projects/previewing-changes.md>) - trying a change set before committing it
- [Recover from rejected changes](<https://docs.dhtmlx.com/planning-engine/wasm/how-to/recover-from-rejected-changes.md>) - handling rejected operations
