How to Retrieve Large Volumes of Data

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.

When importing a large number of items via list methods using standard REST navigation, do not use regular pagination with sequential increments of start = start + 50.

Instead, select pages via a filter by the last received identifier and pass start = -1. This approach disables the total item count calculation and reduces the load on Bitrix24.

During start >= 0, standard REST navigation returns a page of data and calculates the total number of items for the total field. On large datasets or with complex filters, this calculation can be slow.

For a single page of data, a filter by the last identifier is not required. It is sufficient to pass start = -1, so that the method returns up to 50 items without counting total.

Regular navigation of list methods via next and start fields is described in the article List Method Specifics.

How to Select All Items

To sequentially retrieve all items by filter, use methods that support sorting by a stable numeric identifier.

  1. Sort items by identifier in ascending order
  2. Add a >ID or >id condition to the filter with the value of the last received identifier
  3. Pass start = -1 to disable the total count calculation
  4. After each request, retain the identifier of the last item from the response
  5. Repeat the request until the method returns fewer than 50 items

This loop does not use the next field. The next page is generated by the identifier filter.

Considerations for Importing

Leave a delay between requests to avoid exceeding REST API limits. If a method returns a limit error, decrease the request frequency and call again later.

Apply this approach only to methods where filtering and sorting by identifier work with start = -1 in the same way as standard REST navigation. If items are deleted or access permissions change during the import, the selection set may change between requests.

Below is a code example and a comparison of execution time against regular pagination. With 2,387,743 items using identical permissions and filters, the execution time decreased from 49.9 seconds to 0.097 seconds.

Example

$tokenID = 'XXXXXXXXXXXXXXXXXXXXX';
        $host = 'XXXX.bitrix24.com';
        $user = 1;
        
        // Start from scratch or from the ID where the previous import stopped.
        $lastId = 0;
        $finish = false;
        
        while (!$finish)
        {
            $http = new \Bitrix\Main\Web\HttpClient();
            $http->setTimeout(5);
            $http->setStreamTimeout(50);
        
            $json = $http->post(
                'https://'.$host.'/rest/'.$user.'/'.$tokenID.'/crm.item.list/',
                [
                    'entityTypeId' => 1,
                    'order' => ['id' => 'ASC'],
                    'filter' => ['>id' => $lastId],
                    'select' => ['id', 'title', 'createdTime'],
                    'start' => -1,
                ]
            );
        
            $result = \Bitrix\Main\Web\Json::decode($json);
            $items = $result['result'] ?? [];
            $itemsCount = count($items);
        
            if ($itemsCount === 0)
            {
                break;
            }
        
            foreach ($items as $item)
            {
                $lastId = $item['id'];
                // Process the element.
            }
        
            if ($itemsCount < 50)
            {
                $finish = true;
            }
        
            if (!$finish)
            {
                usleep(500000);
            }
        }
        /*
        // Result of the REST request execution with total count calculation.
        Array
        (
            [next] => 50
            [total] => 2387743
            [time] => Array
            (
                [start] => 1770996013.4833
                [finish] => 1770996063.3997
                [duration] => 49.916450023651
                [processing] => 49.899916887283
                [date_start] => 2026-02-13T18:20:13+03:00
                [date_finish] => 2026-02-13T18:21:03+03:00
            )
        )
        // Result of the REST request execution without total count calculation.
        Array
        (
            [total] => 0
            [time] => Array
            (
                [start] => 1770997936.3857
                [finish] => 1770997936.4835
                [duration] => 0.097883939743042
                [processing] => 0.068500995635986
                [date_start] => 2026-02-13T18:52:16+03:00
                [date_finish] => 2026-02-13T18:52:16+03:00
            )
        )
        */