Кодирование данных

Выберите инструмент для разработки с AI-агентом:

  • используйте Битрикс24 Вайбкод, чтобы создать приложение для Битрикс24 по описанию задачи без знания языков программирования. Агент напишет код и разместит приложение на сервере без ручной настройки хостинга
  • используйте MCP-сервер, чтобы разрабатывать интеграцию через REST API в своем проекте. Агент будет обращаться к официальной REST-документации

При отправке REST-запросов специальные символы в параметрах могут нарушить структуру URL. Это приведет к ошибкам или неверным данным.

Например, нужно создать лид с названием John&Martin через входящий вебхук методом crm.lead.add. Если не закодировать & в названии, получится такой URL:

https://b24-abcdef.bitrix24.ru/rest/1/xxxxxxx/crm.lead.add?fields%5BTITLE%5D=John&Martin

После выполнения запроса можно обнаружить, что в названии лида осталось только John. Это произошло из-за того, что символ & разделяет параметры запроса. Если он встречается внутри значения, сервер воспримет его как начало нового параметра, а не как часть данных.

Поэтому у запроса образовалось два параметра:

  • fields[TITLE] со значением John
  • новый параметр Martin без значения

Для корректной работы метода нужно заменить специальный символ на кодированный аналог. Для & это %26. Такое преобразование называется URL-кодированием.

Правильный URL для поставленной задачи:

https://b24-abcdef.bitrix24.ru/rest/1/xxxxxxx/crm.lead.add?fields%5BTITLE%5D=John%26Martin

Какие символы нужно кодировать

Кодируйте имя и значение каждого параметра отдельно. Разделители между ними оставляйте без изменений: ? отделяет строку параметров от пути, = — имя от значения, & — параметры друг от друга. Квадратные скобки в имени fields[TITLE] задают вложенную структуру; в URL такое имя записывают как fields%5BTITLE%5D. После разбора запроса сервер получает исходное имя fields[TITLE].

Символ

Код

&

%26

?

%3F

=

%3D

%

%25

[

%5B

]

%5D

#

%23

+

%2B

пробел

%20

Таблица показывает кодирование символов внутри имени или значения. Например, для значения John&Martin замените & на %26, а & между двумя параметрами оставьте как разделитель. Для кодирования произвольного текста применяйте функцию языка программирования, а не заменяйте символы вручную.

Как кодировать в разных языках

Каждый язык программирования предоставляет встроенную функцию:

  • JavaScript — encodeURIComponent
  • PHP — urlencode
  • Python — urllib.parse.quote_plus
  • Java — URLEncoder.encode

Эти функции кодируют отдельное имя или значение параметра, а не URL целиком. Функции urlencode, quote_plus и URLEncoder.encode передают пробел как +; при разборе параметров формы он снова станет пробелом. Если нужен код %20, используйте rawurlencode в PHP или urllib.parse.quote в Python.

Посмотреть, какие заголовки и параметры получит сервер, можно на тестовом адресе webhook.site. Отправляйте туда только тестовые данные без токена вебхука и персональных данных.

Двойное кодирование для batch-запросов

Метод batch позволяет выполнить несколько запросов за один вызов. Запросы передаются в параметре cmd в виде строк: метод?параметр1=значение&параметр2=7. Но теперь каждая такая строка сама становится значением параметра. Поэтому ее тоже нужно кодировать.

  1. Сначала закодируйте значения внутри вложенного запроса.
  2. Затем закодируйте всю строку вложенного запроса целиком.

Если бы требовалось создать лид из примера выше в рамках пакетного выполнения запросов, URL выглядел бы так:

https://b24-abcdef.bitrix24.ru/rest/1/xxxxxxx/batch?cmd%5B0%5D=crm.lead.add%3Ffields%5BTITLE%5D%3DJohn%2526Martin

Обратите внимание: %26 превратилось в %2526, потому что символ % сам был закодирован как %25.

Если передаете cmd в JSON-теле POST-запроса, всю строку подзапроса дополнительно кодировать не нужно. Подробнее о форматах пакетного запроса читайте в статье Как выполнить пакет запросов batch.

Чтобы избежать ручного кодирования и других сложностей, используйте готовые SDK. Они берут на себя всю работу с URL, кодированием и обработкой ошибок.

Официальные SDK Битрикс24:

Как передавать сложные структуры

Многие методы REST API принимают вложенные данные, например, список телефонов контакта или массив полей. В таких случаях рекомендуется отправлять POST-запросы с телом в формате JSON. Тогда структура сохраняется, и не нужно думать о кодировании отдельных параметров.

Пример лида с несколькими телефонами:

curl -X POST \
-H "Content-Type: application/json" \
-d '{
        "fields": {
            "TITLE": "My company",
            "PHONE": [
                {
                    "VALUE": "112233",
                    "VALUE_TYPE": "WORK"
                },
                {
                    "VALUE": "555888112",
                    "VALUE_TYPE": "OTHER"
                }
            ]
        }
    }' \
https://***/rest/***/crm.lead.add
$data = [
    "fields" => [
        "TITLE" => "My company",
        "PHONE" => [
            [
                "VALUE" => "112233",
                "VALUE_TYPE" => "WORK"
            ],
            [
                "VALUE" => "555888112",
                "VALUE_TYPE" => "OTHER"
            ]
        ]
    ]
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'php script');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_URL, 'https://***/rest/***/crm.lead.add');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$raw = curl_exec($ch);
curl_close($ch);
const data = {
    fields: {
        TITLE: 'My company',
        PHONE: [
            {
                VALUE: '112233',
                VALUE_TYPE: 'WORK'
            },
            {
                VALUE: '555888112',
                VALUE_TYPE: 'OTHER'
            }
        ]
    }
};

fetch('https://***/rest/***/crm.lead.add', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
});

import requests

data = {
    'fields': {
        'TITLE': 'My company',
        'PHONE': [
              {
                    'VALUE': '112233',
                    'VALUE_TYPE': 'WORK'
              },
              {
                    'VALUE': '555888112',
                    'VALUE_TYPE': 'OTHER'
              }
        ]
    }
}

r = requests.post('https://***/rest/***/crm.lead.add', json=data)

Если нет возможности отправить JSON, используйте GET-запрос или обычный POST-запрос. Данные нужно передавать в параметрах запроса, соблюдая правила кодирования.

GET-запрос

GET-запрос для примера выше:

https://***/rest/***/crm.lead.add.json?fields%5BTITLE%5D=My%20company&fields%5BPHONE%5D%5B0%5D%5BVALUE%5D=112233&fields%5BPHONE%5D%5B0%5D%5BVALUE_TYPE%5D=WORK&fields%5BPHONE%5D%5B1%5D%5BVALUE%5D=555888112&fields%5BPHONE%5D%5B1%5D%5BVALUE_TYPE%5D=OTHER

Как собрать такую строку программно:

  • PHP — функция http_build_query превращает массив в правильно закодированную строку.
  • JavaScript — можно использовать библиотеку qs или написать свою функцию.

POST-запрос

При POST-запросе нужно указать правильный заголовок Content-Type и отформатировать тело запроса.

  • application/x-www-form-urlencoded — данные преобразуются в одну строку
  • multipart/form-data — данные разбиваются на части, каждая имеет свои заголовки и отделена строкой-разделителем boundary=SomeBoundary
fields%5BTITLE%5D=My%20company&fields%5BPHONE%5D%5B0%5D%5BVALUE%5D=112233&fields%5BPHONE%5D%5B0%5D%5BVALUE_TYPE%5D=WORK&fields%5BPHONE%5D%5B1%5D%5BVALUE%5D=555888112&fields%5BPHONE%5D%5B1%5D%5BVALUE_TYPE%5D=OTHER
--SomeBoundary
Content-Disposition: form-data; name="fields[TITLE]"

My company
--SomeBoundary
Content-Disposition: form-data; name="fields[PHONE][0][VALUE]"

112233
--SomeBoundary
Content-Disposition: form-data; name="fields[PHONE][0][VALUE_TYPE]"

WORK
--SomeBoundary
Content-Disposition: form-data; name="fields[PHONE][1][VALUE]"

555888112
--SomeBoundary
Content-Disposition: form-data; name="fields[PHONE][1][VALUE_TYPE]"

OTHER
--SomeBoundary--

Порядок параметров

Некоторые методы, например, task.commentitem.add и task.checklistitem.complete, требуют строгого соблюдения порядка передачи параметров. В таких случаях параметры нельзя передавать по имени — как объект в JavaScript или ассоциативный массив в PHP. Иначе результат выполнения будет непредсказуем или метод вернет ошибку.

Для передачи таких параметров используйте массив с числовыми индексами. Индексы должны начинаться с 0.

Пример неправильного добавления комментария к задаче:

curl 'https://***/rest/***/task.commentitem.add?TASKID=123&FIELDS%5BPOST_MESSAGE%5D=test'
CRest::call(
    'task.commentitem.add',
    [
        'TASKID' => 123,
        'FIELDS' => ['POST_MESSAGE' => 'text']
    ]
);
BX24.callMethod(
    'task.commentitem.add',
    {
        TASKID: 123,
        FIELDS: { 'POST_MESSAGE': 'text' }
    }
);

Пример правильного добавления комментария к задаче:

curl 'https://***/rest/***/task.commentitem.add?0=123&1%5BPOST_MESSAGE%5D=test'
CRest::call(
    'task.commentitem.add',
    [
        123,
        ['POST_MESSAGE' => 'text']
    ]
);
BX24.callMethod(
    'task.commentitem.add',
    [
        123,
        { 'POST_MESSAGE': 'text' }
    ]
);