Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 219 additions & 0 deletions api/core-workflow.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
Core Workflow
=============

.. note::

Core Workflows are different from triggers: they control the ticket
create/edit form while someone fills it out, for example by restricting
which values are selectable in another field. The form sends its current
values to Zammad, which evaluates the workflows and returns the resulting
field changes. Unlike triggers, they don't act on existing tickets in the
background.

See the :admin-docs:`Core Workflows admin documentation </system/core-workflows.html>`
for the conceptual/UI-side picture of this feature, and
:admin-docs:`Core Workflows limitations </system/core-workflows/limitations.html>`
for how they can restrict attributes/values you see elsewhere in the API.
Compare to :doc:`Report Profile </api/report-profile>`, whose ``condition``
field, unlike Core Workflow, does validate that referenced fields are real.

List
----

Required permission: ``admin.core_workflow``

``GET``-Request sent: ``/api/v1/core_workflows``

Response:

.. code-block:: json
:force:

# HTTP-Code 200 Ok

[
{
"id": 11,
"name": "Restrict priority for incidents",
"object": "Ticket",
"preferences": {},
"condition_saved": {},
"condition_selected": {
"ticket.type": {
"operator": "is",
"value": ["Incident"]
}
},
"perform": {
"ticket.state_id": {
"operator": "set_fixed_to",
"set_fixed_to": ["new", "open"]
}
},
"active": true,
"stop_after_match": false,
"changeable": true,
"priority": 100,
"updated_by_id": 3,
"created_by_id": 3,
"created_at": "2026-09-24T12:32:01.736Z",
"updated_at": "2026-09-24T12:32:01.736Z"
}
]

.. note::

This endpoint only returns workflows with ``changeable: true``.
Zammad's built-in system workflows are not changeable and are not
included, so the response on a fresh instance is an empty array.
Show, Update and Delete also only operate on changeable workflows.

Show
----

Required permission: ``admin.core_workflow``

``GET``-Request sent: ``/api/v1/core_workflows/{id}``

Response:

.. code-block:: json
:force:

# HTTP-Code 200 Ok

{
"id": 11,
"name": "Restrict priority for incidents",
"object": "Ticket",
"preferences": {},
"condition_saved": {},
"condition_selected": {
"ticket.type": {
"operator": "is",
"value": ["Incident"]
}
},
"perform": {
"ticket.state_id": {
"operator": "set_fixed_to",
"set_fixed_to": ["new", "open"]
}
},
"active": true,
"stop_after_match": false,
"changeable": true,
"priority": 100,
"updated_by_id": 3,
"created_by_id": 3,
"created_at": "2026-09-24T12:32:01.736Z",
"updated_at": "2026-09-24T12:32:01.736Z"
}

Create
------

Required permission: ``admin.core_workflow``

``POST``-Request sent: ``/api/v1/core_workflows``

.. code-block:: json

{
"name": "Restrict priority for incidents",
"object": "Ticket",
"condition_saved": {},
"condition_selected": {
"ticket.type": {
"operator": "is",
"value": ["Incident"]
}
},
"perform": {
"ticket.state_id": {
"operator": "set_fixed_to",
"set_fixed_to": ["new", "open"]
}
},
"active": true,
"stop_after_match": false,
"changeable": true,
"priority": 100
}

Response:

.. code-block:: json
:force:

# HTTP-Code 201 Created

{
"id": 11,
"name": "Restrict priority for incidents",
"object": "Ticket",
"preferences": {},
"condition_saved": {},
"condition_selected": {
"ticket.type": {
"operator": "is",
"value": ["Incident"]
}
},
"perform": {
"ticket.state_id": {
"operator": "set_fixed_to",
"set_fixed_to": ["new", "open"]
}
},
"active": true,
"stop_after_match": false,
"changeable": true,
"priority": 100,
"updated_by_id": 3,
"created_by_id": 3,
"created_at": "2026-09-24T12:32:01.736Z",
"updated_at": "2026-09-24T12:32:01.736Z"
}

.. note::

Core Workflow does *not* validate that fields referenced in
``condition_selected`` or ``perform`` exist. A workflow that references
a field that doesn't exist yet is saved without error. It has no
visible effect in the ticket form until the referenced field exists.

Update
------

Required permission: ``admin.core_workflow``

``PUT``-Request sent: ``/api/v1/core_workflows/{id}``

Same payload shape as Create above. Response is the updated record, same
shape as Show/Create.

.. note::

Sending the full Create payload to an existing workflow's ``id``
updates that record in place. It doesn't create a duplicate.

Delete
------

Required permission: ``admin.core_workflow``

.. danger:: **This is a permanent removal**

Please note that removing core workflows cannot be undone.

``DELETE``-Request sent: ``/api/v1/core_workflows/{id}``

Response:

.. code-block:: json
:force:

# HTTP-Code 200 Ok

{}
Loading
Loading