The Activity tab (/workspace/activity) shows an append-only feed of meaningful changes in the active organization: who did what, on which entity, and when.
Who can see it
Only owners and admins can open the feed. Members and viewers see the standard permission message and the API returns 403.
What is recorded
Each successful domain mutation emits one event per HTTP request, for example:
- Projects, suites, and test cases (create, update, move, archive, delete)
- Custom fields and bundled test-case edits (one
test_case.updatedwhen a PATCH changes fields, steps, or values together) - Members, invitations, and API tokens
- Test runs — create, update, close (including automatic close once every case has a result), abort, delete, clone (“Run again”), add/remove cases, mark cases and steps, assignees, retries, actual-result text edits, and result attachments
Events are stored forever in this release.
Filtering the feed
Use Add filter above the timeline to narrow the organization feed:
- Actor filters to events performed by one organization member. Events whose user was later deleted remain in the feed, but they do not match a member actor filter.
- Entity type filters by the kind of object that changed, such as project, test run, defect, custom field, member, invitation, or API token. Select more than one entity type to OR them together.
Filters are reflected in the URL, so owners and admins can share a narrowed activity view. Changing filters reloads the feed from the newest matching event; use Clear filters to return to the full timeline.
Run activity in the feed
Run events use snapshotted labels so the timeline stays readable even if a case is renamed or deleted later.
| What happened | What you see |
|---|---|
| Run created | Case count plus optional environment, default assignee, and milestone |
| Run updated | Collapsible diff for name, description, default assignee, environment, or milestone |
| Run closed | Final scorecard (passed / failed / blocked / skipped / untested counts, total duration, projected pass/fail). Renders the same whether the run closed automatically (every case got a result) or via Complete. |
| Run deleted | Run name (plain text, no link), final scorecard, and whether it was open or closed at deletion |
| Actual result edited | Step context with from → to text diff on the live execution path |
| Run cloned (“Run again”) | Source run name and the new run’s name/label |
| Cases added | How many cases were appended (up to 20 named in the payload) |
| Case marked | Linked case label (PROJECT-42 · Title), status chip from → to, optional elapsed time |
| Step marked | Case link, step position/action, status chip, case-level status after the mark |
| Case assigned | Who assigned whom (including auto-assign on open vs manual patch) |
| Case retried | Prior status reset to untested and elapsed time cleared when applicable |
| Case removed | Case identity and status at removal |
| Bulk mark / assign / retry / remove | One row per gesture with count, first few case IDs, and an expandable per-case diff (status chips, assignee transitions, or removal status) |
| Bulk submit result | One row per gesture: status, count, first few case IDs, and an expandable per-case status diff (same shape as bulk mark) — split time and any attached defect are not shown in the diff itself |
| Attachment committed/deleted | Case, step, and filenames |
Case links open the run execution view when the run still exists; deleted runs fall back to plain text labels.
Activity inside a run
Each run execution view (/projects/{project}/runs/{run}) includes an Activity tab next to Test cases. It shows the same day-grouped timeline and diff primitives as the workspace feed, but scoped to that run only.
| Surface | Who can open it | API |
|---|---|---|
| Workspace Activity | Owners and admins | GET /api/v1/orgs/{orgUlid}/audit-events |
| Run Activity tab | Any role that can read the run (viewer+) | GET /api/v1/runs/{runUlid}/audit-events |
The tab persists in the URL as ?tab=activity so deep links and the browser back button restore the selection. On a closed run the Test cases tab is read-only, but Activity continues to show the full history. Run links inside the tab are omitted because you are already inside that run.
Timeline layout
The feed is a day-grouped timeline:
- Events are grouped under sticky day headers (Today, Yesterday, or an absolute date) with a per-day count.
- A vertical rail connects round actor avatars within each day.
- Each avatar shows a small action-type badge (create, update, move, or delete) derived from the event action.
Use the footer (showing N events · load more) to page through older entries. Appending a page does not duplicate a day header when new events belong to a day already on screen.
Change details (diff)
Events of type *.updated, *.moved, and member.role_changed carry a structured diff that describes which fields changed and what they changed to:
- All changes (including a single field) appear in one collapsible group labeled with a zero-padded count and the word change or changes by count (e.g.
01 change,03 changes). Expand it to see one row per field with the previous value (muted, strikethrough) and the new value (accent-soft, monospace). - Null values render as Not set without strikethrough.
- Long values: strings are truncated to 240 characters and a See more button reveals the full snapshot saved at the moment of the change.
- Case steps: when a consolidated save changes steps, the feed shows a detailed per-step diff inside the same change group — one row per touched step with a verdict (Added, Removed, Modified, Reordered), field-level
from → tolines for action/data/expected (same neutral styling and See more truncation as scalar fields), position moves, and image add/remove by filename. Historical events may still show the legacy count-only row (Steps: 3 → 5). If more than 20 steps change at once, the first 20 rows appear plus a summary line for the rest (totals by verdict stay accurate). - Custom field definitions:
custom_field.updatedrecords every mutable part of the definition — scalar properties (title,placeholder, Required, default value) asfrom → torows, plus phrase-style lines for project visibility (shown in all projects, switched to specific projects, no projects (same copy as the custom-fields table) when scope is left empty, or added/removed per project with snapshotted project names) and option list edits (added, removed, renamed options with snapshotted names). Pure option reorder still uses the separatecustom_field.options_reorderedaction without option lines. Field and reference names are snapshots from emission time, even if later renamed or deleted. - Milestone, environment, and defect edits:
milestone.updated,environment.updated, anddefect.updatedcarry the same field-level diff as other updates. A milestone shows name, description, dates (start, due, and forecast), and parent milestone by name; status changes — a manual edit or automatic completion — record the statusfrom → to. An environment shows name, slug, description, URL, and the Default flag. A defect shows its assignee and milestone by name. These reference fields render the human-readable label snapshotted at the moment of the change, never the internal id.
Non-update events (*.created, *.deleted, *.archived, *.restored) keep showing their descriptive template without a change group.
Actor types
| Actor | How it appears |
|---|---|
| User | Round initials avatar and display name or email local-part |
| API token | Key icon and the token name you chose at creation |
| System | Neutral icon and label “System” |
If a user or token is deleted later, older events stay in the feed with “Deleted user” / “Deleted token”.
Related API
Integrators can read the same data with GET /api/v1/orgs/{orgUlid}/audit-events. See Audit events API.