Общие правила
Термины
Всё в базе Интеграма — термины: Клиент, Адрес, Статус, Пользователь. Пользователь видит их как таблицы и колонки, разработчик — как типы и их реквизиты. «Таблица Клиент с колонками Адрес и Телефон» и «тип Клиент с реквизитами Адрес и Телефон» — одно и то же.
- Таблица (тип) — термин верхнего уровня. Значение её первой колонки — главное значение записи.
- Колонка (реквизит) — термин, добавленный к таблице. Один термин может быть колонкой у разных таблиц.
- Справочная колонка — ссылка на другую таблицу; в ней хранится id записи справочника.
- Подчинённая таблица — записи, принадлежащие записи родителя (позиции заказа, пункты меню роли).
Адрес команды
Команда — это адрес вида /{база}/{команда}/{id}. Параметр JSON в адресе говорит, что ответ нужен в JSON, а не HTML-страницей.
https://integram.io/{база}/{команда}/{id}?JSON=1
_d_* — изменение структуры (таблиц и колонок), POST;_m_* — изменение данных (записей), POST;metadata, object, report, terms, xsrf — чтение, GET.
Поля POST-запросов передаются формой (-F в curl или application/x-www-form-urlencoded). Значение колонки передаётся полем t{id колонки}, например t41=ivan@example.com.
Имена вместо кодов
Таблицы, записи и запросы можно называть в адресе по именам, не зная их id: ядро ищет термин с таким именем, а для записи — запись с таким главным значением.
| Где | Как | Пример |
|---|
| Таблица в адресе | Имя таблицы вместо её id — в любой команде | metadata/Клиент, object/Клиент, _m_new/Клиент |
| Запись в адресе | Имя таблицы и главное значение записи | edit_obj/Клиент/АО Ромашка, _m_set/Роль/Менеджер |
| Запрос в адресе | Название запроса вместо id | report/Клиенты по категориям |
| Фильтр запроса | Имя колонки в отчёте, пробелы — _ | FR_Дата_заказа=01.10.2026 |
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/metadata/Пользователь?JSON=1"
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/edit_obj/Роль/admin?JSON=1"
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/report/Клиенты%20по%20категориям?JSON_KV"
- пробел в адресе пишется как
%20, остальную кириллицу curl передаёт как есть; - поля записи передаются только кодами
t{id колонки}, фильтры записей — F_{id колонки}: id колонок отдаёт metadata; - если в базе два термина с одним именем, адрес берёт первый найденный — такие таблицы читайте по id.
Ответы и ошибки
Команды _d_* и _m_* отвечают объектом одного вида: id — созданный или изменённый элемент, obj — объект, к которому он относится, warnings — предупреждения.
{"id": 643, "obj": 641, "next_act": "edit_types", "args": "ext", "warnings": ""}
Ошибка приходит массивом с ключом error, и HTTP-статус у неё обычно 200: проверяйте в ответе ключ error, а не только код. Свой статус есть у немногих отказов: 401 — нет авторизации или неверный пароль в auth, 403 — неверный или устаревший _xsrf, 429 — вход временно заблокирован.
[{"error": "Вы хотите удалить реквизит у типа при наличии этого реквизита у экземпляров (всего: 1)!"}]
Авторизация
Токен API
Для программ и интеграций удобнее всего постоянный токен: заведите в базе пользователя (например, api), впишите ему в поле «Токен» случайную строку из 15–64 символов и выдайте роль с нужными правами. Токен передаётся заголовком X-Authorization в каждом запросе.
TOKEN=a3f1c9... # токен пользователя api
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/metadata?JSON=1"
Заголовок читается, только если в адресе или теле запроса есть параметр JSON (JSON, JSON_KV, JSON_OBJ…). Без него запрос считается переходом браузера и уходит на страницу входа.
Вместо X-Authorization подходит Authorization: <токен> или Authorization: Bearer <токен>. Ещё токен можно передать кукой, названной именем базы (mydb), или полем формы token в POST-запросе. Кука нужна командам, работающим с сессией, например файловому менеджеру dir_admin.
curl -s -b "mydb=$TOKEN" "https://integram.io/mydb/metadata?JSON=1"
Простейший вариант — Basic-авторизация: логин и пароль в каждом запросе. По RFC 7617 пара логин:пароль кодируется в Base64, curl делает это сам ключом -u.
curl -s -u "manager:Str0ng-Pass" "https://integram.io/mydb/metadata?JSON=1"
Токен XSRF
Каждый POST-запрос на изменение (_d_*, _m_*) должен нести поле _xsrf. Его выдаёт команда xsrf; заодно она сообщает пользователя, его роль и id.
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/xsrf?JSON=1"
Ответ
{"_xsrf": "cd4b6417a3940ed4a84h074d", "token": "a3f1c9...", "user": "api", "role": "api", "id": "632", "msg": ""}
Получить в переменную (нужен jq)
XSRF=$(curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/xsrf?JSON=1" | jq -r ._xsrf)
Дальше в примерах $TOKEN и $XSRF — эти два значения. _xsrf привязан к токену, которым его получили: запрашивайте его и шлите POST под одним и тем же токеном.
Вход по логину и паролю
Команда auth проверяет логин и пароль и открывает сессию этого устройства. В ответе — токен сессии и _xsrf к нему.
curl -s "https://integram.io/mydb/auth?JSON=1" -F "login=manager" -F "pwd=Str0ng-Pass"
Ответ
{"_xsrf": "1cb413634d074d3804ed48", "token": "s.1824537600.9e0c...", "id": "632", "msg": ""}
Сессия живёт, пока ею пользуются: без запросов она гаснет через 30 дней. Пять неверных паролей подряд блокируют вход на 15 минут, сервер отвечает 429 с заголовком Retry-After.
Выход — GET /{база}/exit гасит текущую сессию, exit?all=1 — все сессии пользователя.
Структура: таблицы и колонки
Базовые типы
Тип каждой колонки — один из базовых. Его код передаётся параметром t при создании термина.
| Код | Тип | Что хранит |
|---|
| 3 | SHORT | Короткая строка (до 127 символов) |
| 8 | CHARS | Строка без ограничения длины |
| 12 | MEMO | Многострочный текст |
| 13 | NUMBER | Целое число |
| 14 | SIGNED | Число с дробной частью |
| 9 | DATE | Дата, 30.10.2026 |
| 4 | DATETIME | Дата и время; через API — unix-время в секундах |
| 11 | BOOLEAN | Да / нет: 1 или пусто |
| 10 | FILE | Файл |
| 2 | HTML | HTML-текст, выводится без экранирования |
| 6 | PWD | Пароль: хранится хешем, на экране — «******» |
| 7 | BUTTON | Кнопка-действие над записью |
| 5 | GRANT | Объект системы — выбор таблицы или колонки |
| 16 | REPORT_COLUMN | Колонка запроса |
| 17 | PATH | Путь к файлу |
Метаданные
Команда metadata без id описывает всю базу, с id — одну таблицу. Отсюда берут id колонок для t{id} в записях и запросах.
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/metadata/18?JSON=1"
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/metadata/Пользователь?JSON=1" # то же по имени
Ответ (сокращён): таблица Пользователь
{
"id": "18", "up": "0", "type": "3", "val": "Пользователь", "unique": "1",
"reqs": [
{"num": 1, "id": "115", "orig": "42", "val": "Роль", "type": "3", "ref": "42", "ref_id": "114",
"attrs": ":!NULL:"},
{"num": 2, "id": "41", "orig": "41", "val": "Email", "type": "3"},
{"num": 4, "id": "156", "orig": "156", "val": "Дата", "type": "9", "attrs": "[TODAY]"}
]
}
id — id таблицы или колонки; val — имя; type — базовый тип;unique — значения первой колонки уникальны;ref — таблица-справочник у справочной колонки, ref_id — id ссылки на неё;orig — термин колонки: у справочной — таблица-справочник, у обычной — сам термин;arr_id — подчинённая таблица;attrs — атрибуты колонки строкой, только если заданы.
Атрибуты хранятся строкой: :!NULL: — обязательное поле, :MULTI: — множественный выбор, :ALIAS=Имя: — псевдоним, а текст вне двоеточий — значение по умолчанию. Например, :!NULL::ALIAS=Исполнитель: — обязательная колонка с псевдонимом.
Список таблиц
Команда terms отдаёт таблицы базы, доступные пользователю: id, базовый тип первой колонки и имя.
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/terms?JSON=1"
Ответ
[{"id": 641, "type": 3, "name": "Клиент"}, {"id": 18, "type": 3, "name": "Пользователь"}, {"id": 42, "type": 3, "name": "Роль"}]
Создать таблицу
_d_new создаёт термин — таблицу из одной колонки. t — базовый тип первой колонки, val — имя, unique=1 — значения первой колонки уникальны (так делают справочники).
curl -s "https://integram.io/mydb/_d_new?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t=3" -F "val=Клиент"
Ответ: id новой таблицы — в obj
{"id": "", "obj": 641, "next_act": "edit_types", "args": "ext", "warnings": ""}
Повторный вызов с тем же именем не создаёт дубль: вернётся id существующего термина и предупреждение в warnings.
Добавить колонку
Колонка добавляется в два шага: создать термин колонки (_d_new) и добавить его к таблице (_d_req). Если подходящий термин уже есть, первый шаг пропускают.
curl -s "https://integram.io/mydb/_d_new?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t=3" -F "val=ИНН"
# → {"obj": 642, ...}
curl -s "https://integram.io/mydb/_d_req/641?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t=642"
# → {"id": 643, "obj": 641, ...}
Id колонки — id из ответа _d_req (643), а не obj: дальше значение этой колонки пишется полем t643.
Колонка-справочник
Справочная колонка ссылается на другую таблицу. Шаги: таблица-справочник, ссылка на неё (_d_ref), ссылка как колонка (_d_req).
curl -s "https://integram.io/mydb/_d_new?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t=3" -F "val=Категория" -F "unique=1"
# → {"obj": 644}
curl -s "https://integram.io/mydb/_d_ref/644?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF"
# → {"obj": 645} — ссылка на Категорию
curl -s "https://integram.io/mydb/_d_req/641?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t=645"
# → {"id": 646} — колонка Категория у Клиента
Множественный выбор включает и выключает _d_multi на колонке:
curl -s "https://integram.io/mydb/_d_multi/646?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF"
Если в таблице несколько колонок со ссылкой на один справочник (Автор, Исполнитель, Контролёр — все из Пользователя), дайте им псевдонимы через _d_alias с id колонки:
curl -s "https://integram.io/mydb/_d_alias/648?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "val=Исполнитель"
Подчинённая таблица
Табличная часть (позиции заказа, этапы проекта) — это таблица, добавленная к другой таблице через _d_req без ссылки. Её записи создаются с родителем up={id записи}.
curl -s "https://integram.io/mydb/_d_new?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t=3" -F "val=Позиция"
# → {"obj": 700}
curl -s "https://integram.io/mydb/_d_req/690?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t=700" # 690 — таблица Заказ
Обязательность и значение по умолчанию
_d_null переключает обязательность колонки. _d_attrs задаёт значение по умолчанию: константу или переменную: [TODAY] — сегодня, [USER_ID] — текущий пользователь. Результат виден в attrs колонки в metadata.
curl -s "https://integram.io/mydb/_d_null/643?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF"
curl -s "https://integram.io/mydb/_d_attrs/650?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "val=[TODAY]"
Переместить и удалить
_d_ord ставит колонку на позицию order (первую колонку двигать нельзя), _d_up — на одну позицию выше.
curl -s "https://integram.io/mydb/_d_ord/648?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "order=1"
_d_del_req удаляет колонку. Если в ней есть данные, сервер откажет; forced=1 удаляет вместе с данными. Сам термин колонки остаётся и может пригодиться в другой таблице.
curl -s "https://integram.io/mydb/_d_del_req/643?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "forced=1"
_d_del удаляет пустую таблицу или неиспользуемый термин. Порядок для таблицы с данными: записи, затем ссылки на неё и доступы, затем сама таблица.
curl -s "https://integram.io/mydb/_d_del/642?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF"
_d_save переименовывает таблицу или меняет её базовый тип: val — имя, t — базовый тип, unique=1 — признак уникальности.
Записи
Прочитать записи
Команда object с id таблицы отдаёт её записи. Формат JSON_OBJ — массив строк: i — id записи, u — родитель, o — порядок, r — значения колонок по порядку метаданных.
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/object/641/?JSON_OBJ&LIMIT=100"
Ответ
[
{"i": 649, "u": 1, "o": 1, "r": ["АО Ромашка", "7701234567", "660:Клиент"]},
{"i": 668, "u": 1, "o": 2, "r": ["ПАО Эллипс", "7709876543", "650:Лид"]}
]
Справочное значение приходит как id:Название, множественное — id1,id2:Название1,Название2.
| Параметр | Что делает |
|---|
F_{id колонки}=значение | Фильтр по колонке |
F_{id таблицы}=значение | Фильтр по первой колонке: её ключ — id самой таблицы |
FR_{колонка}=…&TO_{колонка}=… | Диапазон: от и до |
F_U={id родителя} | Записи подчинённой таблицы у одного родителя |
F_I={id записи} | Одна запись |
ORDER={id колонки} | Сортировка; ORDER=-{id} — по убыванию |
LIMIT=100 · LIMIT=100,100 | Первые 100 записей · 100 записей, начиная со 101-й |
_count= | Только число записей: {"count": "42"} |
full=1 | Не обрезать длинные значения |
В значении фильтра работают условия: %ООО% — содержит, !значение — не равно, >100, <=20002, 10..20 — между, % — непусто, !% — пусто, IN(a,b) — одно из значений, @660 — ссылка на запись 660, @IN(21006,21014) — на одну из записей, [TODAY] и другие переменные.
# клиенты, в названии которых есть «Ромашка»: %25 — это % в адресе
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/object/641/?JSON_OBJ&F_641=%25Ромашка%25"
# позиции заказа 691
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/object/700/?JSON_OBJ&F_U=691"
# таблица по имени, фильтр — по id колонки ИНН
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/object/Клиент?JSON_OBJ&F_643=7701234567"
Подчинённую таблицу без F_U сервер отдаёт пустой: её записи висят на родителях, а не на корне.
Создать запись
_m_new с id таблицы. Главное значение записи пишется в t{id таблицы}, колонки — в t{id колонки}. up=1 — запись верхнего уровня, up={id записи} — подчинённая.
curl -s "https://integram.io/mydb/_m_new/641?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=1" -F "t641=АО Ромашка" -F "t643=7701234567" -F "t646=660"
Ответ
{"id": 649, "obj": 649, "ord": 1, "next_act": "object", "args": "", "val": "АО Ромашка"}
В справочную колонку пишется id записи справочника (t646=660). Позиция заказа 691:
curl -s "https://integram.io/mydb/_m_new/700?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "up=691" -F "t700=Труба 32 мм" -F "t702=12"
Изменить запись
_m_set с id записи меняет переданные колонки, включая первую. Пустое значение очищает поле, у BOOLEAN снимают галку значением 0.
curl -s "https://integram.io/mydb/_m_set/649?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t643=7701234568" -F "t646=661"
Признак удачной записи — "obj": 649 (id записи) и непустой id в ответе. В справочный ключ t{id} _m_set принимает только id; пробел (t646= ) очищает одиночную ссылку.
Запись можно назвать в адресе по имени таблицы и главному значению:
curl -s "https://integram.io/mydb/_m_set/Клиент/АО%20Ромашка?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t643=7701234568" -F "t646=661"
В колонку с множественным выбором передают id записей через запятую: t648=616,617.
Варианты для справочной колонки отдаёт _ref_reqs с id колонки; параметр id — запись, для которой выбирают значение:
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/_ref_reqs/646?JSON=1&id=649"
# → {"650": "Лид", "660": "Клиент", "661": "ЧС"}
Удалить и переместить
_m_del удаляет запись вместе с подчинёнными; если на неё ссылаются другие записи, сервер откажет ошибкой в error. _m_move переносит подчинённую запись к другому родителю, _m_up поднимает её на одну позицию среди соседей, _m_ord ставит на позицию order.
curl -s "https://integram.io/mydb/_m_del/668?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF"
curl -s "https://integram.io/mydb/_m_move/705?JSON=1&up=692" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF"
Все записи под фильтром удаляет object с _m_del_select. Записи, на которые есть ссылки, остаются. Ответ — переадресация, число удалённых — в параметре deleted её адреса:
curl -s -o /dev/null -w "%{redirect_url}\n" "https://integram.io/mydb/object/641/?JSON=1&F_646=650" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "_m_del_select=1"
# → …/object/641?…&deleted=31
Загрузка файлом
Тысячи записей загружают файлом: object/{таблица} с import=1 и файлом bki_file. Строка файла — значения колонок через ; в порядке метаданных, первой строкой — DATA. Справочные колонки задаются названиями, даты — ДД.ММ.ГГГГ, ; внутри значения экранируется как \;. Если первая колонка уникальна, существующие записи обновляются.
clients.bki
DATA
АО Ромашка;7701234567;Клиент;;
ПАО Эллипс;7709876543;Лид;;
curl -s "https://integram.io/mydb/object/641?JSON&import=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "bki_file=@clients.bki;type=text/plain"
Файл — до 8 МБ; большие объёмы делите на части по несколько тысяч строк. Для подчинённой таблицы добавьте в адрес F_U={id родителя}.
Пользователи, роли и доступ
Системные таблицы
Пользователи, роли, меню, доступы и запросы — обычные таблицы базы. Их записи создаются и меняются теми же _m_new, _m_set и _m_del.
| Таблица | id | Колонки |
|---|
| Пользователь | 18 | t18 логин, t115 роль, t20 пароль, t33 имя, t41 email, t125 токен API |
| Роль | 42 | t42 название, t135 описание |
| Объекты (доступы роли) | 116 | t116 объект, t136 уровень, t49 маска; подчинена роли |
| Меню | 151 | t151 название, t153 адрес, t391 иконка; подчинено роли |
| Запрос | 22 | t22 название; колонки запроса — таблица 28 |
| Функция | 63 | Справочник функций колонок запроса: SUM, COUNT, abn_ID… |
Колонки Activity (t124) и xsrf (t40) заполняет сервер — не пишите в них. Неудачные входы ядро integram.io считает в журнале базы, а не в колонке пользователя.
Создать роль
curl -s "https://integram.io/mydb/_m_new/42?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=1" -F "t42=Менеджер" -F "t135=Ведёт клиентов и заказы"
# → {"id": 900, ...}
Роли базы — object/42/?JSON_OBJ. Роль admin с полным доступом — запись 145. Id роли по названию:
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/object/Роль?JSON_OBJ&F_42=Менеджер"
# → [{"i": 900, "u": 1, "o": 1, "r": ["Менеджер", "", "", "Ведёт клиентов и заказы"]}]
Создать пользователя и задать пароль
Пользователь — запись таблицы 18: логин в t18, роль в t115, пароль в t20. Пароль сохраняется хешем, прочитать его обратно нельзя.
curl -s "https://integram.io/mydb/_m_new/18?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=1" -F "t18=ivanov" -F "t115=900" -F "t20=Str0ng-Pass" -F "t33=Иван Иванов" -F "t41=ivanov@example.com"
# → {"id": 910, ...}
Сменить пароль или роль — _m_set с id пользователя. Открытые сессии смена пароля не закрывает: выйти на всех устройствах — exit?all=1 под токеном этого пользователя.
curl -s "https://integram.io/mydb/_m_set/910?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t20=N3w-Pass"
curl -s "https://integram.io/mydb/_m_set/910?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "t115=901"
Пользователь для интеграции получает вместо пароля токен API в t125 — с ним он работает заголовком X-Authorization (см. «Токен API»):
curl -s "https://integram.io/mydb/_m_new/18?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=1" -F "t18=api" -F "t115=900" -F "t125=$(openssl rand -hex 32)"
Выдать доступ
Доступ роли к таблице, колонке или запросу — запись таблицы 116, подчинённая роли: up — роль, t116 — объект, t136 — уровень.
| t136 | Уровень |
|---|
| 53 | READ — чтение |
| 54 | WRITE — чтение и изменение |
| 52 | BARRED — нет доступа (колонка не приходит даже в API) |
curl -s "https://integram.io/mydb/_m_new/116?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=900" -F "t116=641" -F "t136=54" # Клиент: запись
curl -s "https://integram.io/mydb/_m_new/116?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=900" -F "t116=644" -F "t136=53" # Категория: чтение
curl -s "https://integram.io/mydb/_m_new/116?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=900" -F "t116=643" -F "t136=52" # колонка ИНН скрыта
Уровень таблицы наследуют её колонки; отдельной колонке его можно понизить. Кроме таблиц в t116 бывают особые объекты: 0 — редактор структуры (WRITE на него нужен для команд _d_*), 1 — все таблицы, 10 — файловый менеджер. Поля t55 и t56 разрешают роли выгрузку и удаление.
Новая таблица не выдана ни одной роли: без доступа её записи отвечают 403, а выпадающий список справочника пуст. Выдавайте доступ сразу после _d_new всем ролям, чьи экраны ею пользуются.
Доступы роли — object/116/?JSON_OBJ&F_U={роль}, роли с доступом к таблице — object/42/?JSON_OBJ&F_116={таблица}.
Маски: только свои записи
Маска t49 у доступа фильтрует строки, которые увидит роль. Её значение работает как фильтр F_ по колонке из t116.
# менеджер видит только клиентов, где он — ответственный (колонка 651 ссылается на Пользователя)
curl -s "https://integram.io/mydb/_m_new/116?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=900" -F "t116=651" -F "t136=54" -F "t49=[USER_ID]"
# пользователь видит в таблице Пользователь только себя
curl -s "https://integram.io/mydb/_m_new/116?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=900" -F "t116=18" -F "t136=53" -F "t49=[USER]"
- переменные:
[USER] — логин, [USER_ID] — id пользователя, [ROLE], [ROLE_ID]; - значение или условие:
164, %ООО%, @IN(21006,21014); [Имя запроса] — подставляется первая ячейка первой строки запроса, например список id через GROUP_CONCAT;- маски на одну колонку складываются по ИЛИ, на разные колонки — по И.
Гостевой доступ
Посетитель без входа работает пользователем guest, если в базе есть и роль guest, и пользователь guest с этой ролью. Что видит гость, решают доступы и меню роли guest.
Запросы (отчёты)
Как устроен запрос
Запрос — запись таблицы 22, его колонки — записи таблицы 28 с up={id запроса}. У колонки есть источник (таблица или колонка), имя, формула, фильтр и функция. Как соединить таблицы и по чему группировать, ядро определяет само по метаданным.
| Поле | Что задаёт |
|---|
t28 | Источник: id таблицы (её главное значение) или id колонки; 0 — вычисляемая колонка |
t100 | Имя в отчёте: ключ в JSON_KV и имя фильтра FR_{имя}. Без имени колонку снаружи не отфильтровать |
t101 | Формула: у колонки с источником — псевдоним (одно слово), у вычисляемой — SQL-выражение над псевдонимами |
t102 / t103 | Фильтр: значение от / до |
t104 | Функция: SUM, COUNT, AVG, MIN, MAX, GROUP_CONCAT; abn_ID — id записи |
t105 / t106 | Фильтр по значению функции (HAVING) |
t107 | 1 — скрыть колонку: она фильтрует и связывает, но не выводится |
t109 | Сортировка: 1, 2…; минус — по убыванию |
t84 | Формат: NUMBER, SIGNED, DATE, HTML |
t72 | Итог по колонке в форме отчёта: SUM, COUNT |
Первая колонка задаёт главную таблицу: строки отчёта — её записи. Колонки связанных таблиц добавляются просто id их колонок — путь по ссылкам ядро находит само.
Создать запрос
Отчёт «Клиенты по категориям»: категория, число клиентов и сумма заказов.
curl -s "https://integram.io/mydb/_m_new/22?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "up=1" -F "t22=Клиенты по категориям"
# → {"id": 950}
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=950" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=950" -F "t28=646" -F "t100=Категория" -F "t109=1"
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=950" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=950" -F "t28=641" -F "t100=Клиентов" -F "t104=COUNT" -F "t72=SUM"
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=950" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=950" -F "t28=695" -F "t100=Сумма" -F "t104=SUM" -F "t84=NUMBER"
GROUP BY строится по всем видимым колонкам без функции — здесь по Категории. В _m_new функцию можно указать именем (t104=SUM), в _m_set — только id записи из таблицы Функция: object/63/?JSON_OBJ.
Колонки запроса — object/28/?JSON_OBJ&F_U=950, список запросов — object/22/?JSON_OBJ.
Формулы и вычисляемые колонки
Колонке-источнику дают псевдоним в t101, вычисляемая колонка (t28=0) использует его в SQL-выражении. В формуле — псевдоним, а не имя в отчёте.
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=960" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=960" -F "t28=720" -F "t100=Мест" -F "t101=мест" -F "t107=1"
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=960" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=960" -F "t28=721" -F "t100=Куплено" -F "t101=куплено"
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=960" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=960" -F "t28=0" -F "t100=Загрузка, %" -F "t101=ROUND(куплено/мест*100, 2)"
- псевдоним — одно слово, не совпадающее с SQL-словами (
id, val, SUM); - агрегат внутри формулы:
ROUND(SUM(Оценка), 1); [THIS] — собственное значение колонки: COALESCE([THIS], 0);- ссылка:
CONCAT('<a href="', Адрес, '">открыть</a>') с t84=HTML; SELECT, FROM, TABLE в формулах запрещены — выборка из другой таблицы делается подзапросом.
Фильтры
Постоянный фильтр задаётся в t102 (от) и t103 (до) у колонки. Колонку только для фильтра скрывают (t107=1). Если у колонки нет «Имени в отчёте» (t100), её фильтр снаружи не переопределить — так задают ограничители, см. «Права на запрос».
| t102 | Отбирает |
|---|
Одобрена | Равно значению; у справочной колонки — по названию |
660 при t104=abn_ID | Ссылка на запись справочника 660 |
% / !% | Непусто / пусто |
!1 | Не равно 1 |
>=[WEEK_AGO], [TODAY], [YESTERDAY], [MONTH_AGO], [NOW] | Относительные даты |
1.1 и t103=31.12 | Диапазон дат текущего года |
[USER_ID] при t104=abn_ID | Строки текущего пользователя |
_request_.ProjID | Параметр из адреса: report/950?ProjID=12 |
[Имя запроса] | Значение другого запроса |
# только свои заказы: колонка Ответственный (697) скрыта и фильтрует по текущему пользователю
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=950" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=950" -F "t28=697" -F "t104=abn_ID" -F "t102=[USER_ID]" -F "t107=1"
Подзапросы
Суммы с разных уровней цепочки (Компания ← Заявка ← Договор) в одном запросе удваиваются: строки соединённых таблиц перемножаются. Каждую следующую сумму считают отдельным запросом и вставляют в формулу как [Имя запроса].
# подзапрос «Договоры компании»: сумма договоров компании [КомпанияID]
curl -s "https://integram.io/mydb/_m_new/22?JSON=1" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=1" -F "t22=Договоры компании"
# → {"id": 970}
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=970" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=970" -F "t28=812" -F "t100=Сумма" -F "t104=SUM"
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=970" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=970" -F "t28=803" -F "t104=abn_ID" -F "t102=[КомпанияID]" -F "t107=1"
# основной запрос: псевдоним КомпанияID и вычисляемая колонка с подзапросом
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=980" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=980" -F "t28=800" -F "t100=КомпанияID" -F "t101=КомпанияID" -F "t104=abn_ID" -F "t107=1"
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=980" \
-H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" \
-F "up=980" -F "t28=0" -F "t100=Законтрактовано" -F "t101=IFNULL([Договоры компании],0)"
Подзапрос без строк возвращает пусто — оберните его в IFNULL или задайте запросу «Если пусто, вернуть» (t113=0).
Выполнить запрос
report с id или названием запроса. JSON_KV — массив объектов с ключами из t100; JSON — с описанием колонок и форматов.
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/report/950?JSON_KV"
Ответ
[
{"Категория": "Клиент", "Клиентов": "12", "Сумма": "1840000"},
{"Категория": "Лид", "Клиентов": "31", "Сумма": "0"}
]
Фильтры снаружи — FR_{имя} (от) и TO_{имя} (до), пробелы в имени заменяются на _. Они работают на колонках с заполненным «Именем в отчёте» (t100) и перекрывают их t102/t103; колонки без имени параметрами не меняются. ORDER={id колонки} сортирует (минус — по убыванию), LIMIT ограничивает число строк, RECORD_COUNT возвращает только их число.
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/report/950?JSON_KV&FR_Категория=Клиент"
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/report/951?JSON_KV&FR_Дата=01.10.2026&TO_Дата=31.10.2026&LIMIT=50"
# запрос по названию
curl -s -H "X-Authorization: $TOKEN" "https://integram.io/mydb/report/Клиенты%20по%20категориям?JSON_KV&FR_Категория=Клиент"
Права на запрос
Запрос работает как хранимая процедура: с правами того, кто его настроил, а не того, кто вызывает. Роли нужен только доступ READ к самому запросу (t116={id запроса}, t136=53). Он открывает все колонки и строки, которые отбирает запрос; доступы роли к таблицам и её маски к запросу не применяются.
Это не обход прав, а назначение запроса: отдать ровно то, что решил аналитик, в том числе из таблиц, которые роль руками не видит. Что увидит вызывающий, ограничивают фильтры внутри запроса, и внешний параметр их не отменит:
- снаружи фильтруются только колонки с заполненным «Именем в отчёте» (
t100): FR_{имя} и TO_{имя} перекрывают их t102/t103; - у колонки без
t100 фильтр t102/t103 параметрами адреса не переопределяется — это защита от подмены фильтра пользователем; - фильтруемость включается явно, именем колонки: всё, чему аналитик не дал имени, закрыто для подмены. Это строже правила «фильтровать можно всё, кроме запрещённого».
# ограничитель «только свои заказы»: без t100, скрыт — FR_/TO_ его не заменят
curl -s "https://integram.io/mydb/_m_new/28?JSON=1&up=950" -H "X-Authorization: $TOKEN" -F "_xsrf=$XSRF" -F "up=950" -F "t28=697" -F "t104=abn_ID" -F "t102=[USER_ID]" -F "t107=1"
Не давайте колонке-ограничителю «Имя в отчёте». С именем её фильтр становится параметром: вызывающий подставит в FR_ чужой id вместо [USER_ID] и получит чужие строки.