Skip to content

Workflow activities overview ​

A workflow activity is one entry in the audit trail of a project workflow. Each entry records who changed the workflow, what changed, and the old and new values. The feed is read-only.

Entries come from workflow changes made in Plane. Through this API, only hook writes record entries: creating, updating, or deleting a workflow hook adds an entry with field set to transition_rule. Workflow, state, and transition writes through this API record no entry. Plane writes entries in the background after each change, so an entry can appear a moment after the write that caused it.

Learn more about workflows

The workflow activity object ​

Attributes ​

  • id string (uuid)

    Unique identifier for the entry.

  • workflow_id string (uuid)

    The workflow the entry belongs to.

  • actor_id string (uuid)

    The user who made the change. null when no user is recorded.

  • state_id string (uuid)

    The state the change applies to. For transition, approver, and hook changes, it is the transition's source state. For type, creation, and default changes, it is the state itself. It is null for workflow-level changes such as a rename and for states added to the workflow. An entry for an added state names the state in new_identifier.

  • verb string

    What happened. Values include created, added, updated, removed, deleted, enabled, and disabled.

  • field string

    The part of the workflow that changed. The values include workflow, workflow_name, workflow_description, workflow_is_active, workflow_work_item_type, workflow_state, workflow_default_state, workflow_type, allow_work_item_creation, state_transition, state_approvers, rejected_state, transition_rule, reset, and is_workflow_enabled. This is a partial list.

  • old_value string

    The value before the change, as text. null when there was none.

  • new_value string

    The value after the change, as text. For a transition_rule entry, it is the hook's handler_name.

  • old_identifier string (uuid)

    The id of the record the old value refers to, when it refers to one. For an updated or removed transition_rule entry, it is the hook id.

  • new_identifier string (uuid)

    The id of the record the new value refers to, when it refers to one. For an added or updated transition_rule entry, it is the hook id.

  • epoch number

    When the change happened, in Unix seconds.

  • created_at string (date-time)

    When the entry was recorded. This is the value created_at__gt filters on.

Response200
json
{
  "id": "a41d7c93-5e28-4b06-9f17-3c8e2b6d0a54",
  "workflow_id": "9e3f6a2c-7b14-4d8e-a5c1-2f60b8d4e719",
  "actor_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
  "state_id": "2c4d16f8-9b3e-4a52-8d71-1f0e6c9a5b48",
  "verb": "added",
  "field": "transition_rule",
  "old_value": null,
  "new_value": "send_webhook",
  "old_identifier": null,
  "new_identifier": "3b7e9a15-6c2d-4f84-9b31-0e5d8c7a2f69",
  "epoch": 1768382561.0,
  "created_at": "2026-01-14T09:22:41.478363Z"
}

Endpoints ​

MethodPathDescription
GET/api/v2/workspaces/{slug}/projects/{project_id}/workflows/{workflow_id}/activities/List workflow activities
GET/api/v2/workspaces/{slug}/projects/{project_id}/workflows/{workflow_id}/activities/{pk}/Get a workflow activity

Polling for changes ​

The list sorts oldest first by default. To read only what is new since your last poll, pass the created_at of the newest entry you already hold as ?created_at__gt=. The filter uses a strict greater-than comparison, so the list does not return that entry again.

Governed workspaces ​

In a workspace with workspace governance turned on, workflows live in the workspace catalog and have no project. These project routes look the workflow up by project, so they return 404 for a catalog workflow, the same as the sibling workflow state and transition routes. Read the feed of a catalog workflow with Workspace workflow activities. Those routes serve the same entries in the same shape and take the same filters.

Response shaping ​

Every workflow activity read accepts ?fields= for sparse responses. See Sparse fields. Errors follow the shared problem+json contract.