Help Center

BPMN processes

Cloud Pyrus
Cloudless Pyrus

If a form uses a BPMN diagram, its tasks move through the diagram blocks rather than through steps. In the API, diagram blocks are called nodes, and the arrows between them are called flows.

A task's position in the process is described by tokens. A token is a marker placed on a diagram node that shows where the task currently is and what it's waiting for. A task can have several tokens at once: for example, after an AND gateway, each parallel branch gets its own token. When the branches merge, their tokens complete, and a new token continues along the diagram.

The API methods described in this section let you:

  • find out which nodes a task is at and whose action it's waiting for;
  • see how a comment moved a task along the diagram;
  • approve a task at a specific node, resume a suspended process, or move a token manually;
  • get the description of a form's BPMN diagram and the list of its versions;
  • find tasks in the form register that are at specific nodes.

BPMN fields in the form description

The GET /forms and GET /forms/{form-id} methods return two additional fields in the form description:

use_bpmn_for_new_tasksBoolean. true means new form tasks are created and move according to the BPMN diagram.
bpmn_versionInteger. The number of the diagram version used for new tasks. Returned only if use_bpmn_for_new_tasks = true.
{
  "id": 1204,
  "name": "Payment request",
  "use_bpmn_for_new_tasks": true,
  "bpmn_version": 3
}

BPMN task fields

For tasks based on a BPMN diagram, the GET /tasks/{task-id} method returns additional fields. Tasks that follow regular routing don't have these fields.

bpmn_versionInteger. The number of the diagram version the task follows.
bpmn_suspendedBoolean. true means the task has tokens suspended due to an error.
bpmn_tokensArray of tokens: the nodes the task is currently at. Not returned if there are no tokens.

The bpmn_tokens element

token_idInteger. Token ID.
node_idInteger. ID of the node the token is at.
node_nameString. Node name. May be missing.
node_typeString. Node type. May be missing.
statusString. Token status.
personThe user whose action is awaited. May be missing.
event_typeString. Awaited event. Returned only for waiting nodes.
event_timeDate and time when the event fires. Returned only for Timer nodes.
GET https://api.pyrus.com/v4/tasks/91827364

Response body

{
  "task": {
    "id": 91827364,
    "text": "Payment request for invoice No. 4417",
    "form_id": 1204,
    "bpmn_version": 3,
    "bpmn_suspended": false,
    "bpmn_tokens": [
      {
        "token_id": 1,
        "node_id": 12,
        "node_name": "Legal approval",
        "node_type": "Activity",
        "status": "Active",
        "person": {
          "id": 4471,
          "first_name": "Mary",
          "last_name": "Smith"
        }
      },
      {
        "token_id": 2,
        "node_id": 18,
        "node_name": "Wait 3 business days",
        "node_type": "Timer",
        "status": "Waiting",
        "event_type": "Timer",
        "event_time": "2026-09-05T09:00:00Z"
      }
    ]
    // ...
  }
}

In this example, the task is in two parallel branches at once: in one, it's waiting for legal approval, and in the other, for a timer to fire.

BPMN fields in task comments

If a comment moved a task along the diagram, the comment contains the bpmn_transitions array. If the comment didn't move any tokens, the field is not returned.

The bpmn_transitions element

token_idInteger. Token ID.
node_idInteger. ID of the node the token moved to. Not returned if the token completed.
node_nameString. Node name. May be missing.

If an element contains only token_id, the comment completed this token, and the token no longer exists. Tokens that the comment created and immediately completed are not included in the array.

{
  "id": 55510293,
  "text": "Approved",
  "approval_choice": "approved",
  "bpmn_transitions": [
    { "token_id": 1 },
    { "token_id": 2 },
    { "token_id": 7, "node_id": 24, "node_name": "Payment" }
  ]
}

In this example, tokens 1 and 2 completed at the merge gateway, and token 7 continued along the diagram in their place.

Actions on BPMN tasks

The POST /tasks/{task-id}/comments method accepts additional parameters for tasks based on a BPMN diagram. All of them are optional.

bpmn_node_idInteger. ID of the node at which you approve the task. Passed together with the approval_choice parameter.
bpmn_resume_processingBoolean. true resumes processing of tokens suspended due to an error. false has no effect.
bpmn_token_movesArray of objects specifying which tokens to move manually and to which nodes. Each object contains two required fields:
  • token_id — ID of the token to move;
  • node_id — ID of the node to move the token to.

Approving at a specific node

If a task has split into parallel branches and the user's action is awaited at several nodes at once, specify the node you're acting at in bpmn_node_id.

POST https://api.pyrus.com/v4/tasks/91827364/comments

Request body

{
  "text": "No objections",
  "approval_choice": "approved",
  "bpmn_node_id": 12
}

Response body

{
  "task": {
    "id": 91827364,
    "bpmn_version": 3,
    "bpmn_suspended": false,
    "bpmn_tokens": [
      {
        "token_id": 1,
        "node_id": 20,
        "node_name": "Accounting review",
        "node_type": "Activity",
        "status": "Active",
        "person": {
          "id": 1731,
          "first_name": "Bob",
          "last_name": "Johnson"
        }
      },
      {
        "token_id": 2,
        "node_id": 18,
        "node_name": "Wait 3 business days",
        "node_type": "Timer",
        "status": "Waiting",
        "event_type": "Timer",
        "event_time": "2026-09-05T09:00:00Z"
      }
    ],
    "comments": [
      // ...
      {
        "id": 55510294,
        "text": "No objections",
        "approval_choice": "approved",
        "bpmn_transitions": [
          { "token_id": 1, "node_id": 20, "node_name": "Accounting review" }
        ]
      }
    ]
    // ...
  }
}

Resuming after an error

If a token was suspended due to an error ("status": "Suspended", and the task has "bpmn_suspended": true), fix the cause and resume processing. The token continues from the same node.

POST https://api.pyrus.com/v4/tasks/91827364/comments

Request body

{
  "text": "Bot access granted, resuming",
  "bpmn_resume_processing": true
}

Response body

{
  "task": {
    "id": 91827364,
    "bpmn_version": 3,
    "bpmn_suspended": false,
    "bpmn_tokens": [
      {
        "token_id": 3,
        "node_id": 15,
        "node_name": "Upload invoice",
        "node_type": "Activity",
        "status": "Active"
      }
    ],
    "comments": [
      // ...
      {
        "id": 55510295,
        "text": "Bot access granted, resuming"
      }
    ]
    // ...
  }
}

Moving tokens manually

You can move a token to another node, bypassing the routing conditions. You can move several tokens in one comment.

POST https://api.pyrus.com/v4/tasks/91827364/comments

Request body

{
  "text": "Returning for revision",
  "bpmn_token_moves": [
    { "token_id": 1, "node_id": 8 }
  ]
}

Response body

{
  "task": {
    "id": 91827364,
    "bpmn_version": 3,
    "bpmn_suspended": false,
    "bpmn_tokens": [
      {
        "token_id": 1,
        "node_id": 8,
        "node_name": "Prepare request",
        "node_type": "Activity",
        "status": "Active",
        "person": {
          "id": 1731,
          "first_name": "Bob",
          "last_name": "Johnson"
        }
      }
    ],
    "comments": [
      // ...
      {
        "id": 55510296,
        "text": "Returning for revision",
        "bpmn_transitions": [
          { "token_id": 1, "node_id": 8, "node_name": "Prepare request" }
        ]
      }
    ]
    // ...
  }
}

curl

curl -X POST \
  'https://api.pyrus.com/v4/tasks/91827364/comments' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "text": "Returning for revision",
    "bpmn_token_moves": [
      { "token_id": 1, "node_id": 8 }
    ]
}'

Note: you can't move a token to the node it's already at, and you can't move it from one parallel branch to another. The bpmn_resume_processing and bpmn_token_moves actions are not performed in a closed task — reopen it first.

Filtering the form register by diagram nodes

The GET /forms/{form-id}/register method accepts two additional parameters for forms with a BPMN diagram. You can combine them with other register filters.

bpmn_nodesDiagram node IDs. Only tasks with at least one token at one of the specified nodes are returned. In a GET request, pass the IDs separated by commas; in a POST request, pass them as an array. If the parameter is missing or empty, the filter is not applied.
bpmn_suspendedtrue (or y) returns only tasks with tokens suspended due to an error; false (or n) returns only tasks without such tokens. If the parameter is missing, the filter is not applied.

GET request example:

GET https://api.pyrus.com/v4/forms/1204/register?bpmn_nodes=12,18

The same as a POST request, with the parameters in the request body:

{
  "bpmn_nodes": [12, 18],
  "bpmn_suspended": false
}

Nodes in the list are combined with OR: it's enough for a token to be at any of them. If you specify the ID of a node that doesn't exist, you won't get an error, but the result will be empty.

Tip: you can get node IDs using the GET /forms/{form-id}/bpmn/{bpmn-version} method.

GET /forms/{form-id}/bpmn

This method returns the list of BPMN diagram versions of a form. It's available to anyone with access to the form.

GET https://api.pyrus.com/v4/forms/1204/bpmn

Response body

{
  "form_id": 1204,
  "active_bpmn_version": 3,
  "versions": [
    {
      "bpmn_version": 4,
      "description": "Draft with legal review",
      "create_date": "2026-09-20T08:15:00Z",
      "author": {
        "id": 4471,
        "first_name": "Mary",
        "last_name": "Smith",
        "type": "user"
      }
    },
    {
      "bpmn_version": 3,
      "create_date": "2026-08-01T10:00:00Z"
    }
  ]
}

curl

curl -X GET \
  'https://api.pyrus.com/v4/forms/1204/bpmn' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>'

Response fields

form_idInteger. Form ID.
active_bpmn_versionInteger. The number of the version used for new tasks. Returned only if the form has use_bpmn_for_new_tasks = true.
versionsArray of diagram versions in descending order of number, including deleted ones. An empty array if there are no versions. Each version contains the following fields:
  • bpmn_version — version number;
  • description — version description (may be missing);
  • create_date — creation date;
  • delete_date — deletion date (only for deleted versions);
  • author — the version author (may be missing).

GET /forms/{form-id}/bpmn/{bpmn-version}

This method returns the description of the specified BPMN diagram version of a form: nodes, flows between them, field visibility conditions, and text frames. It's available to anyone with access to the form.

Every form always has version 0: until it's saved, it's returned empty. A deleted version is returned too, with the delete_date field. Empty arrays are not included in the response.

GET https://api.pyrus.com/v4/forms/1204/bpmn/3

Response body

{
  "form_id": 1204,
  "bpmn_version": 3,
  "active_bpmn_version": 3,
  "create_date": "2026-08-01T10:00:00Z",
  "active_task_nodes": [12],
  "nodes": [
    {
      "id": 1,
      "node_type": "Start",
      "position": { "x": 40, "y": 200 },
      "flows": [ { "id": 1, "to_node_id": 12 } ]
    },
    {
      "id": 12,
      "node_type": "Activity",
      "description": "Legal approval",
      "participant": {
        "person": {
          "id": 4471,
          "first_name": "Mary",
          "last_name": "Smith",
          "type": "user"
        }
      },
      "actions": ["Approve", "Reject"],
      "position": { "x": 240, "y": 200 },
      "flows": [ { "id": 2, "to_node_id": 2 } ]
    },
    {
      "id": 2,
      "node_type": "Finish",
      "position": { "x": 440, "y": 200 }
    }
  ],
  "field_visibility_conditions": [
    {
      "field_id": 7,
      "condition": { "field_id": 5, "condition_type": 3 }
    }
  ]
}

curl

curl -X GET \
  'https://api.pyrus.com/v4/forms/1204/bpmn/3' \
  -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>'

Response fields

form_idInteger. Form ID.
bpmn_versionInteger. Version number.
active_bpmn_versionInteger. The number of the version used for new tasks. Returned only if the form has use_bpmn_for_new_tasks = true.
descriptionString. Version description. May be missing.
create_dateVersion creation date. Not returned for an unsaved version 0.
delete_dateVersion deletion date. Returned only for deleted versions.
authorThe user who created the version. May be missing.
active_task_nodesArray of integers. IDs of nodes where task tokens are currently located.
nodesArray of diagram nodes.
deleted_nodesArray of deleted nodes. Tasks may still be moving through them, and tokens in bpmn_tokens may refer to them.
field_visibility_conditionsArray of form field visibility conditions in this version. Each element contains the following fields:
  • field_id — ID of the form field whose visibility is set;
  • condition — the condition under which the field is visible.
framesArray of text frames on the diagram. Each frame contains the following fields:
  • id — frame ID;
  • description — frame text;
  • position — frame coordinates: x, y;
  • size — frame size: w (width), h (height).

The nodes element

The format is the same for the nodes and deleted_nodes arrays.

idInteger. Node ID. Matches node_id in bpmn_tokens and bpmn_transitions.
node_typeString. Node type.
descriptionString. Node name. May be missing.
participantObject: the participant whose action is awaited.
subprocess_configurationObject: subprocess settings. Returned only for Subprocess nodes.
timerObject: timer settings. Returned only for Timer nodes.
awaiting_statusesArray of integers. Task statuses the node waits for. Returned only for AwaitingStatus nodes.
task_statusInteger. The status assigned to the task when it reaches the node.
actionsArray of strings. Actions available to the participant: Approve, Reject, Acknowledge, Complete, Sign.
reference_node_idInteger. The related node: for an AND_Split node, its matching AND_Join node.
flow_group_idInteger. The AND gateway branch the node belongs to.
positionObject. Node coordinates on the diagram: x, y.
flowsArray of outgoing flows.
deleted_flowsArray of deleted outgoing flows.

The participant element

personObject: a user, role, or bot. The format is the same as for a user; the type is specified in the type field.
contact_field_idInteger. The Contact field the participant is taken from.
contact_field_form_field_idInteger. The field of the linked form, if the contact is taken from it.
queue_node_idInteger. The queue node the participant is taken from.
workflow_catalog_columnObject. The participant is taken from a catalog column. Contains the catalog_id, column_id, column_name, field_id, and is_manager fields.
workflow_by_department_columnObject. The participant is taken from the org chart. Contains the catalog_id, column_id, and column_name fields, as well as apply_to_task_author or contact_field_id.

The flows element

The format is the same for the flows and deleted_flows arrays.

idInteger. Flow ID.
to_node_idInteger. ID of the node the flow leads to.
conditionObject: the transition condition. May be missing.
is_defaultBoolean. The default transition of an XOR gateway. Returned only if true.
vertex_noInteger. The gateway vertex the flow leaves from.
to_vertex_noInteger. The gateway vertex the flow enters.
hint_positionObject. Coordinates of the condition label on the diagram: x, y.

The timer element

modeString. How time is counted: RelativeTime — calendar time, RelativeOrgWorkTime — the organization's working hours.
daysInteger. Days.
hoursInteger. Hours.
minutesInteger. Minutes.

The subprocess_configuration element

The format is the same as for subprocess settings in the form description.

subprocess_form_idInteger. ID of the subprocess form.
wait_until_subprocess_finishedBoolean. Whether to wait for the subprocess to finish.
field_mappingsArray. Mapping between the fields of the main form and the subprocess form.
update_main_fields_modeString. When to update the main task fields.
update_main_fields_on_stepInteger. The step at which the main task fields are updated.
finish_subprocess_tasks_when_main_is_finishedBoolean. Whether to close subprocess tasks together with the main task.
subprocess_guidString. ID of the subprocess setting.
map_changes_only_on_subprocess_stepBoolean. Transfer changes only at the subprocess step.

The condition element

The format is the same as for routing conditions in the form description.

field_idInteger. The form field the condition checks.
condition_typeInteger. Condition type.
valueString. The value to compare with.
valuesArray of strings. The values to compare with.
catalog_columnInteger. Catalog column. Only for catalog fields.
childrenArray of nested conditions.

Enumeration values

Token status (status)

ActiveThe token is waiting for a user's action.
WaitingThe token is waiting for an event: a timer firing or the task reaching a certain status.
CompletedThe token has reached the end of the process.
SuspendedThe token was suspended due to an error. To continue, use the bpmn_resume_processing parameter.
TerminatedThe task was forcibly closed.

Node type (node_type)

StartProcess start.
FinishProcess finish.
ActivityAction.
XORXOR gateway.
AND_SplitSplit AND gateway.
AND_JoinMerge AND gateway.
SubprocessSubprocess.
QueueQueue.
TimerTimer (waiting for a period of time).
AwaitingStatusTimer (awaiting status).

Learn more about diagram blocks in BPMN workflow.

Awaited event (event_type)

TimerA timer fires.
AwaitingStatusThe task reaches the required status.

Error codes

CodeDescription
bpmn_token_not_foundThe token wasn't found in the task, or there is no action awaiting your approval at the specified node. Occurs if bpmn_token_moves contains a non-existent token_id, or if bpmn_node_id passed with approval_choice points to a node where you have no active action.
bpmn_node_not_foundThe process diagram has no node to move the token to. Occurs if bpmn_token_moves contains an invalid node_id.
bpmn_invalid_token_moveThe token can't be moved: the target node is the same as the current one, the diagram structure doesn't allow the move (for example, from one parallel branch to another), or the same token_id is specified twice in the request.
bpmn_engine_failureThe task's process diagram couldn't be processed. This usually means the form or the diagram was deleted, or the diagram version is unavailable. May occur during any action on a BPMN task.
bpmn_task_closedThe task is closed. The bpmn_resume_processing and bpmn_token_moves actions are not performed in a closed task — reopen it first.
bpmn_diagram_version_not_foundThe form doesn't have the specified diagram version. Occurs in the GET /forms/{form-id}/bpmn/{bpmn-version} method.
access_denied_formNo access to the form (HTTP 403). Occurs in the GET /forms/{form-id}/bpmn and GET /forms/{form-id}/bpmn/{bpmn-version} methods.

Note: apps that use the PyrusApiClient library version 2.1.11.1 or earlier get the server_error error instead of these codes.

Was this article helpful?