Change History
TruePPM records a change history for tasks, projects, dependencies, sprints, and more. Each edit captures a field-level diff — the old value, the new value, and when it happened — so you can answer “when did this task’s finish date slip, and why?” without a spreadsheet.
Viewing a task’s history
Section titled “Viewing a task’s history”Open a task in the Schedule view and switch to the task drawer’s Activity tab — the “All events” timeline there is where task history renders; there is no separate History tab. You’ll see a reverse chronological list of changes, each tagged with its type:
+Created — the object was added.~Updated — one or more fields changed; the diff lists each field with its old and new value.−Deleted — the object was removed.
Each entry shows how long ago the change happened. Project admins also see who made the change; Members and Viewers see the change itself but not the user, by design. Long histories paginate with a Load more control.
What is and isn’t tracked
Section titled “What is and isn’t tracked”History deliberately excludes fields the scheduling engine recalculates on its own — the earliest/latest a task could start and finish, its float (how many days it can slip before it delays the project), and whether it’s on the critical path — along with internal bookkeeping used to keep your data in sync across devices. Those recompute automatically on every schedule run, so recording them would bury the changes you actually care about — duration, status, percent complete, planned dates, assignee, and notes — under recalculation noise.
| Method & path | Returns |
|---|---|
GET /api/v1/projects/{id}/tasks/{taskId}/history/ | Paginated field-level diffs for one task |
GET /api/v1/projects/{id}/history/ | Paginated project-level field changes, plus a count_truncated flag |
Any project Viewer or above can read history. The identity of the editing user
(history_user) is included only for Admins — for everyone else the field is
present but null, so a client should treat it as optional rather than absent.
The project-level endpoint materializes at most a fixed number of records before
paginating. When that cap is reached it sets count_truncated: true alongside the
usual {count, next, previous, results} envelope, meaning older history exists but
is not reachable through this endpoint.
Activity feed (shipped in 0.4)
Section titled “Activity feed (shipped in 0.4)”The per-task history endpoint gained an opt-in ?include= parameter in 0.4
that merges non-diff activity into the same feed:
?include= token | Adds events |
|---|---|
comments | comment_added, comment_edited, comment_deleted |
time | time_logged (scoped to your own entries) |
attachments | attachment_uploaded |
schedule | cpm_recalculated, baseline_drift_detected (system events, actor is null) |
risks | risk_linked, risk_unlinked |
all | all of the above |
Without ?include, the response is unchanged. With it, every entry — including
field-diff changes — carries a consistent {event_type, actor, timestamp, detail}
shape, and actor is null for authorless or system-generated events. Time-log
events are deliberately limited to the requesting user’s own entries, matching the
privacy boundary of the time-tracking endpoints.
The schedule events are written by the CPM engine: a cpm_recalculated row is
recorded whenever a recompute moves a task’s early/late dates, and a
baseline_drift_detected row the moment a task first crosses past its active
baseline finish. Both are system-generated, so their actor is null. The risks
events record when a risk is linked to or unlinked from the task, with the acting
member as actor.
Retention
Section titled “Retention”For your TruePPM administrator: history rows are cleared out by a nightly purge job after 90 days by default. See Outbox & Record Retention to tune or disable it.