TaskData#

One task as the engine imports it: id, place in the hierarchy, dates, duration, scheduling flags and leveling inputs. It appears as an entry of ProjectData.tasks and of tasks.add in a SchedulingChanges set. To change an existing task, send a TaskUpdate instead.

Field names are snake_case and type is spelled without a prefix. A record must be a JSON object. Unknown fields are ignored, so task objects with extra UI properties can be sent as they are. null in any optional field reads as the default. See Wire format.

Fields#

Field Type Required Default Description
id Id yes - Task id. Unique among tasks; 1 and "1" are the same id
parent Id | null no no parent Id of the parent summary. "" and a value equal to config.root_id also mean no parent
type "task" | "summary" | "project" | "milestone" no "task" "task" (leaf), "summary", "project" (input alias of "summary") or "milestone"
start_date DateValue | null no absent Start date
end_date DateValue | null no absent End date. Can't be before start_date
duration number | null no absent Working time in duration_unit. Fractional values are allowed; negative ones are rejected
duration_unit TimeUnit | null no config.duration_unit Unit of duration, leveling_delay and pauses: "minute", "hour" or "day"
constraint_type ConstraintType | null no none "asap", "alap", "snet", "snlt", "fnet", "fnlt", "mso" or "mfo". Acts only when config.apply_constraints is true
constraint_date DateValue | null no absent Date of a dated constraint. Required when constraint_type is anything other than "asap" or "alap"
auto_scheduling boolean | null no true false fixes the task: it's never moved, but its links still push successors
unscheduled boolean | null no false true leaves the task and its descendants out of the plan; no dates are needed
progress number | null no 0 Completion from 0 to 1. With config.use_progress, 1 marks the task completed and fixed
priority number | null no 500 Leveling priority, a whole number from 0 to 1000. 1000 means the task is never leveled
leveling_delay number | null no 0 Elapsed time added before the task's driven start, in duration_unit (a day is 24 hours). Not negative
pauses Pause[] | null no [] Leveling splits, sorted by at and non-overlapping. Ignored on summaries, milestones and unscheduled tasks
calendar_id Id | null no "global" calendar Calendar the task works on. Must name a calendar in ProjectData.calendars. With calendar_mode: "task-inherited", a task without one uses its nearest ancestor's

Which dates a task needs depends on type:

  • "task": two of start_date, end_date and duration. The third is derived. If all three are sent, they must agree on the task's calendar.
  • "summary": both dates or neither. Its span is rolled up from its children, so start_date + duration is rejected. A summary without dates needs a dated child.
  • "milestone": start_date or end_date. Its duration is 0.

leveling_delay and pauses are normally written by level. See Leveling resources before setting them by hand.

The validation errors these fields produce, and their paths, are listed in Project data.

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.

Used by#

Example#

A summary with two leaf tasks, a milestone and a fixed task measured in hours:

[
  { "id": "phase", "type": "summary" },
  { "id": "design", "parent": "phase", "start_date": "2026-08-10 08:00", "duration": 3 },
  { "id": "build", "parent": "phase", "start_date": "2026-08-13 08:00", "end_date": "2026-08-20 08:00", "priority": 800 },
  { "id": "release", "type": "milestone", "start_date": "2026-08-20 08:00" },
  {
    "id": "audit",
    "start_date": "2026-08-10 08:00",
    "duration": 12,
    "duration_unit": "hour",
    "auto_scheduling": false
  }
]