How to Retrieve a Sales Funnel for a Specific Direction with Semantics for Each Stage of the Deal

Scope: crm

Who can execute the method: users with administrative access to the CRM section

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

This example outputs all existing deal directions along with the semantics for each stage.

var arCategory = [];
        
        BX24.callMethod('crm.dealcategory.list', {}, function(result) {
            if (result.error()) {
                console.error(result.error());
            } else {
                arCategory = result.data().reduce(function(acc, item) {
                    acc[item.ID] = item.NAME;
                    return acc;
                }, {});
        
                BX24.callMethod('crm.dealcategory.default.get', {}, function(result) {
                    if (result.error()) {
                        console.error(result.error());
                    } else {
                        arCategory[result.data().ID] = result.data().NAME;
        
                        Object.keys(arCategory).forEach(function(id) {
                            var entity_id = id > 0 ? 'DEAL_STAGE_' + id : 'DEAL_STAGE';
        
                            BX24.callMethod('crm.status.list', { filter: { ENTITY_ID: entity_id } }, function(resultDeal) {
                                if (resultDeal.error()) {
                                    console.error(resultDeal.error());
                                } else {
                                    var table = document.createElement('table');
                                    var caption = document.createElement('caption');
                                    caption.textContent = arCategory[id];
                                    table.appendChild(caption);
        
                                    var thead = document.createElement('thead');
                                    var trHead = document.createElement('tr');
                                    ['STATUS ID', 'NAME', 'SEMANTICS'].forEach(function(text) {
                                        var th = document.createElement('th');
                                        th.textContent = text;
                                        trHead.appendChild(th);
                                    });
                                    thead.appendChild(trHead);
                                    table.appendChild(thead);
        
                                    var tbody = document.createElement('tbody');
                                    resultDeal.data().forEach(function(item) {
                                        var tr = document.createElement('tr');
                                        if (item.EXTRA && item.EXTRA.COLOR) {
                                            tr.style.color = item.EXTRA.COLOR;
                                        }
                                        ['STATUS_ID', 'NAME', 'EXTRA.SEMANTICS'].forEach(function(key) {
                                            var td = document.createElement('td');
                                            td.textContent = key.split('.').reduce(function(acc, k) {
                                                return acc && acc[k];
                                            }, item);
                                            tr.appendChild(td);
                                        });
                                        tbody.appendChild(tr);
                                    });
                                    table.appendChild(tbody);
        
                                    document.body.appendChild(table);
                                }
                            });
                        });
                    }
                });
            }
        });
        

Note

To use the PHP examples, configure the CRest class and include the crest.php file in the files where this class is used. Learn more

$arCategory = [];
        $result = CRest::call('crm.dealcategory.list');
        if (!empty($result['result']))
        {
            $arCategory = array_column($result['result'], 'NAME', 'ID');
        }
        $result = CRest::call('crm.dealcategory.default.get');//get name default deal category
        if (!empty($result['result']))
        {
            $arCategory[$result['result']['ID']] = $result['result']['NAME'];
        }
        foreach ($arCategory as $id => $name):
            if ($id > 0)
            {
                $entity_id = 'DEAL_STAGE_' . $id;
            }
            else
            {
                $entity_id = 'DEAL_STAGE';
            }
            $resultDeal = CRest::call('crm.status.list', ['filter' => ['ENTITY_ID' => $entity_id]]);
            if (!empty($resultDeal['result'])):
        ?>
                <table>
                    <caption><?=$name?></caption>
                    <thead>
                    <tr>
                        <th>STATUS ID</th>
                        <th>NAME</th>
                        <th>SEMANTICS</th>
                    </tr>
                    </thead>
                    <tbody>
                    <? foreach ($resultDeal['result'] as $item): ?>
                    <tr <?=(!empty($item['EXTRA']['COLOR']) ? ' style="color:' . $item['EXTRA']['COLOR'] . '"' : '');?>>
                        <td><?=$item['STATUS_ID']?></td>
                        <td><?=$item['NAME']?></td>
                        <td><?=$item['EXTRA']['SEMANTICS']?></td>
                    <tr>
                        <? endforeach; ?>
                    </tbody>
                </table>
            <? endif; ?>
        <? endforeach; ?>
        
from b24pysdk import BitrixWebhook, Client
        from b24pysdk.errors import BitrixAPIError
        
        client = Client(
            BitrixWebhook(
                domain="your-domain.bitrix24.com",
                auth_token="your-webhook-token",
            )
        )
        
        try:
            categories = client.crm.category.list(entity_type_id=2).response.result.get("categories", [])
            category_map = {item["id"]: item["name"] for item in categories}
        
            for category_id, category_name in category_map.items():
                entity_id = f"DEAL_STAGE_{category_id}" if int(category_id) > 0 else "DEAL_STAGE"
                result_deal = client.crm.status.list(
                    filter={"ENTITY_ID": entity_id},
                ).response.result
        
                print(category_name)
                print("STATUS ID\tNAME\tSEMANTICS")
                for item in result_deal:
                    print(
                        "\t".join(
                            [
                                str(item.get("STATUS_ID", "")),
                                str(item.get("NAME", "")),
                                str((item.get("EXTRA") or {}).get("SEMANTICS", "")),
                            ]
                        )
                    )
        except BitrixAPIError as error:
            print(error)