How to Mass Terminate Workflows with Date Filtering

Scope: bizproc

Who can execute methods: administrator

If you are developing integrations for Bitrix24 using AI tools (Codex, Claude Code, Cursor), connect to the MCP server so that the assistant can utilize the official REST documentation.

During the operation of Bitrix24, you may accumulate stuck workflows or processes that remain in the "In Progress" status for too long and become irrelevant.

To mass terminate old workflows, we will sequentially execute two methods:

  1. bizproc.workflow.instances — retrieve a filtered list of processes
  2. bizproc.workflow.kill — terminate workflows with data deletion. If you need to preserve the fact that the workflow was initiated, use the bizproc.workflow.terminate method. Both methods are called in the same way.

1. Retrieve the List of Processes

We will use the bizproc.workflow.instances method with a filter:

  • <STARTED — specify the start date with the prefix <, only processes that were started before this date will be selected.

How to Use Examples in Documentation

BX24.callMethod(
            'bizproc.workflow.instances',
            {
                filter: {
                    '<STARTED': '2025-01-01T00:00:00Z'
                }
            },
        );
        
require_once('crest.php');
        
        $result = CRest::call(
            'bizproc.workflow.instances',
            [
                'filter' => [
                    '<STARTED' => '2025-01-01T00:00:00Z'
                ]
            ]
        );
        
from b24pysdk import BitrixWebhook, Client
        from b24pysdk.errors import BitrixAPIError
        
        
        client = Client(
            BitrixWebhook(
                domain="your-domain.bitrix24.com",
                auth_token="your-webhook-token",
            )
        )
        
        response = client.bizproc.workflow.instances(
            filter={
                "<STARTED": "2025-01-01T00:00:00Z",
            }
        ).response
        

As a result, we will obtain the ID of all active workflows that were initiated before the specified date.

{
            "result": [
                {
                    "ID": "660e559f34af10.95144732",
                    "MODIFIED": "2024-12-04T10:04:24+03:00",
                    "OWNED_UNTIL": null
                },
                {
                    "ID": "6639c7b59e9eb5.40607056",
                    "MODIFIED": "2024-12-04T09:52:40+03:00",
                    "OWNED_UNTIL": null
                },
                {
                    "ID": "66ea9200131729.26195442",
                    "MODIFIED": "2024-09-18T11:42:28+03:00",
                    "OWNED_UNTIL": null
                },
                {
                    "ID": "65ef0868368978.47049110",
                    "MODIFIED": "2024-03-11T16:34:32+03:00",
                    "OWNED_UNTIL": null
                }
            ],
            "total": 4
        }
        

2. Terminate Workflows

We will use the bizproc.workflow.kill method with the parameter:

  • ID — the identifier of the process, we pass the ID obtained in step 1.
BX24.callMethod(
            'bizproc.workflow.kill',
            {
                ID: '660e559f34af10.95144732',
            },
        );
        
require_once('crest.php');
        
        $result = CRest::call(
            'bizproc.workflow.kill',
            [
                'ID' => '660e559f34af10.95144732'
            ]
        );
        
response = client.bizproc.workflow.kill(
            bitrix_id="660e559f34af10.95144732",
        ).response
        

As a result, we will receive true, indicating that the process was successfully deleted. If you encounter an error, refer to the documentation for possible errors in the bizproc.workflow.kill method.

{
            "result": true
        }
        

Code Example

In this example, all found processes are deleted in a loop. When deleting a large volume of data, there may be limitations on request execution. To optimize the code for your workload, refer to the Performance section.

// Function to convert date from dd.mm.yyyy format to ISO format
        function convertDateToISO(dateString) {
            const [day, month, year] = dateString.split('.');
            return `${year}-${month}-${day}T00:00:00Z`;
        }
        
        // Request date from user
        const userDateInput = prompt("Enter the date in dd.mm.yyyy format:");
        const isoDate = convertDateToISO(userDateInput);
        
        // Call the bizproc.workflow.instances method with date filter
        BX24.callMethod(
            'bizproc.workflow.instances',
            {
                filter: {
                    '<STARTED': isoDate
                }
            },
            function(result) {
                if (result.error()) {
                    console.error(result.error());
                } else {
                    const instances = result.data();
                    instances.forEach(instance => {
                        const instanceId = instance.ID;
                        
                        // Call the bizproc.workflow.kill method for each ID
                        BX24.callMethod(
                            'bizproc.workflow.kill',
                            {
                                ID: instanceId
                            },
                            function(killResult) {
                                if (killResult.error()) {
                                    console.error(`Error deleting process ${instanceId}:`, killResult.error());
                                } else {
                                    console.log(`Process ${instanceId} successfully deleted.`);
                                }
                            }
                        );
                    });
        
                    if (result.more()) {
                        result.next();
                    }
                }
            }
        );
        
require_once('crest.php');
        
        // Function to convert date from dd.mm.yyyy format to ISO format
        function convertDateToISO($dateString) {
            list($day, $month, $year) = explode('.', $dateString);
            return "{$year}-{$month}-{$day}T00:00:00Z";
        }
        
        // Request date from user
        $userDateInput = readline("Enter the date in dd.mm.yyyy format: ");
        $isoDate = convertDateToISO($userDateInput);
        
        // Call the bizproc.workflow.instances method with date filter
        $result = CRest::call(
            'bizproc.workflow.instances',
            [
                'filter' => [
                    '<STARTED' => $isoDate
                ]
            ]
        );
        
        if (!empty($result['error'])) {
            echo "Error: " . $result['error_description'];
        } else {
            $instances = $result['result'];
            foreach ($instances as $instance) {
                $instanceId = $instance['ID'];
        
                // Call the bizproc.workflow.kill method for each ID
                $killResult = CRest::call(
                    'bizproc.workflow.kill',
                    [
                        'ID' => $instanceId
                    ]
                );
        
                if (!empty($killResult['error'])) {
                    echo "Error deleting process {$instanceId}: " . $killResult['error_description'] . "\n";
                } else {
                    echo "Process {$instanceId} successfully deleted.\n";
                }
            }
        
            // Check for additional data
            while (!empty($result['next'])) {
                $result = CRest::call(
                    'bizproc.workflow.instances',
                    [
                        'filter' => [
                            '<STARTED' => $isoDate
                        ],
                        'start' => $result['next']
                    ]
                );
        
                $instances = $result['result'];
                foreach ($instances as $instance) {
                    $instanceId = $instance['ID'];
        
                    // Call the bizproc.workflow.kill method for each ID
                    $killResult = CRest::call(
                        'bizproc.workflow.kill',
                        [
                            'ID' => $instanceId
                        ]
                    );
        
                    if (!empty($killResult['error'])) {
                        echo "Error deleting process {$instanceId}: " . $killResult['error_description'] . "\n";
                    } else {
                        echo "Process {$instanceId} successfully deleted.\n";
                    }
                }
            }
        }
        
from b24pysdk import BitrixWebhook, Client
        
        user_date_input = input("Enter the date in dd.mm.yyyy format: ")
        day, month, year = user_date_input.split(".")
        iso_date = f"{year}-{month}-{day}T00:00:00Z"
        
        client = Client(
            BitrixWebhook(
                domain="your-domain.bitrix24.com",
                auth_token="your-webhook-token",
            )
        )
        
        start = None
        while True:
            kwargs = {"filter": {"<STARTED": iso_date}}
            if start is not None:
                kwargs["start"] = start
        
            response = client.bizproc.workflow.instances(**kwargs).response
            instances = response.result or []
        
            for instance in instances:
                instance_id = instance["ID"]
                try:
                    client.bizproc.workflow.kill(bitrix_id=instance_id).response
                except BitrixAPIError as error:
                    print(f"Error deleting process {instance_id}: {error}")
                else:
                    print(f"Process {instance_id} successfully deleted.")
        
            if response.next is None:
                break
            start = response.next