Документация пользовательского API Loomio
/api/user0 — пользовательский API для интеграций с Loomio. Он использует API-ключ учётной записи пользователя, и каждое действие выполняется от имени этого пользователя.
Операции с группами учитывают участие в группах и права в них пользователя, которому принадлежит API-ключ. Статус администратора экземпляра Loomio не расширяет доступ API-ключа к группам или содержимому; для администрирования на уровне экземпляра используйте серверный API.
Используйте API-ключ учётной записи Loomio, от имени которой будут выполняться действия. Отдельная учётная запись бота полезна, если интеграция не должна получать приглашения в опросы или уведомления.
Пользователи, вошедшие в систему, могут найти свой API-ключ и идентификаторы групп на странице доступа к API.
Передавайте API-ключ в заголовке Authorization: Bearer. API-ключи в строках запроса отклоняются, поскольку URL могут записываться прокси-серверами и журналами доступа.
Authorization: Bearer YOUR_API_KEY
В примерах используются YOUR_API_KEY, идентификатор группы 123 и https://www.loomio.com/. Замените их вашим API-ключом, идентификатором группы и URL вашей установки Loomio.
Отправка тел запросов
Отправляйте JSON с заголовком Content-Type: application/json. В примерах cURL используется --json, который устанавливает этот заголовок автоматически. Конечные точки создания и редактирования обсуждений, комментариев и опросов принимают как плоский объект, так и объект, вложенный под именем ресурса, например {"poll": {...}}.
Передавайте массивы как массивы JSON, например "options": ["foo", "bar"]. Если вместо этого вы используете кодирование формы, имена полей массивов должны содержать квадратные скобки, например options[]=foo&options[]=bar; при повторении options=foo&options=bar сохраняется только последнее значение.
Проверяйте HTTP-статус и тело ответа после каждого запроса. При ошибке проверки данных возвращается 422 с объектом errors; при успешном создании опроса сам опрос возвращается в polls, а его варианты — в poll_options.
Обзор конечных точек
| Метод | Конечная точка | Назначение |
|---|---|---|
POST |
/api/user0/comments |
Создать комментарий или ответ |
PATCH |
/api/user0/comments/:id |
Изменить комментарий |
DELETE |
/api/user0/comments/:id |
Удалить комментарий с сохранением записи |
POST |
/api/user0/discussions |
Создать обсуждение |
GET |
/api/user0/discussions/:id |
Получить обсуждение |
GET |
/api/user0/discussions |
Получить список обсуждений в группе |
PATCH |
/api/user0/discussions/:id |
Изменить обсуждение |
DELETE |
/api/user0/discussions/:id |
Удалить обсуждение с сохранением записи |
GET |
/api/user0/groups |
Получить список групп пользователя, которому принадлежит API-ключ |
GET |
/api/user0/groups/:id_or_key_or_handle |
Получить доступную группу |
GET |
/api/user0/memberships |
Получить список записей об участии в группе |
POST |
/api/user0/memberships |
Добавить участников и при необходимости удалить участников, отсутствующих в списке |
GET |
/api/user0/reports |
Сформировать отчёт об участии |
POST |
/api/user0/polls |
Создать опрос |
GET |
/api/user0/polls/:id |
Получить опрос |
GET |
/api/user0/polls |
Получить список опросов в группе |
PATCH |
/api/user0/polls/:id |
Изменить опрос |
DELETE |
/api/user0/polls/:id |
Удалить опрос с сохранением записи |
GET |
/api/user0/search |
Найти доступные обсуждения, комментарии, опросы, голоса и выводы |
GET |
/api/user0/threads |
Получить список доступных веток обсуждений и отдельных опросов |
GET |
/api/user0/threads/:topic_id |
Получить ветку |
GET |
/api/user0/threads/:topic_id/items |
Получить упорядоченные элементы ветки |
GET |
/api/user0/threads/:topic_id/markdown |
Получить полную ветку в формате Markdown |
GET |
/api/user0/chatbots |
Получить список интеграций чата и вебхуков группы |
POST |
/api/user0/chatbots |
Создать интеграцию чата или вебхук |
PATCH |
/api/user0/chatbots/:id |
Обновить интеграцию чата или вебхук |
DELETE |
/api/user0/chatbots/:id |
Удалить интеграцию чата или вебхук |
POST |
/api/user0/chatbots/check |
Отправить тестовое сообщение для проверки соединения с вебхуком |
Постраничная выдача
Конечные точки обсуждений, групп, записей об участии в группах, опросов, веток, элементов веток и вебхуков принимают limit (по умолчанию 50) и offset (по умолчанию 0). Для групп, элементов веток и вебхуков значение limit ограничено числом 500.
Чтобы получить следующую страницу, увеличьте offset на количество возвращённых основных записей. meta.total — полное количество записей, соответствующих запросу; связанные записи не учитываются в размере страницы.
Отчёты об участии возвращают все запрошенные данные, а поиск — до 20 результатов. Ни отчёты, ни поиск не поддерживают постраничную выдачу.
Конечные точки обсуждений, опросов и записей об участии в группах также принимают устаревшие псевдонимы per для limit и from для offset. Для новых интеграций используйте limit и offset.
Связанные записи
Ответы пользовательского API имеют составной формат: вместе с основными записями возвращаются связанные записи, например темы, группы, пользователи, опросы и реакции. Это позволяет клиенту заполнить локальное хранилище записей одним запросом, но ответ может содержать больше данных, чем нужно простой интеграции.
Передайте compact=1, чтобы исключить объёмные связанные записи тем, групп, родительских групп, участия в группах, реакций, тегов и переводов. Основные записи и связанные записи, необходимые для интерпретации их содержимого, остаются в ответе.
curl 'https://www.loomio.com/api/user0/threads/123/items?compact=1' \
-H 'Authorization: Bearer YOUR_API_KEY'
Для прямого управления передайте exclude_types с типами записей в единственном числе, разделёнными пробелами. Например, exclude_types=group reaction исключает связанные группы и реакции. Часто используемые значения: topic, group, parent, membership, reaction, tag, translation, user, discussion, poll, poll_option, stance, stance_choice, outcome и topic_item. Исключения применяются к связанным записям, а не к основному ресурсу, запрошенному через конечную точку.
Ответы со списками включают meta.total, если для списка определён точный размер. Общее количество рассчитывается до применения limit и offset. Конечные точки, такие как поиск, которые намеренно возвращают ограниченный набор результатов, не включают meta.total, а не возвращают null.
Комментарии
Создание комментария
Создайте комментарий в обсуждении от имени пользователя, которому принадлежит API-ключ.
POST /api/user0/comments
Параметры
| Название | Описание |
|---|---|
discussion_id |
Целое число, обязательный параметр. ID обсуждения, в котором нужно оставить комментарий |
body |
Текст комментария, обязателен, если нет вложения |
body_format |
md или html, необязательный параметр, по умолчанию md |
Пример
curl https://www.loomio.com/api/user0/comments \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"discussion_id": 123,
"body": "example comment",
"body_format": "md"
}'
Редактирование комментария
Отредактируйте комментарий от имени пользователя, которому принадлежит API-ключ. Действуют те же права доступа, что и в Loomio: у пользователя должно быть право редактировать этот комментарий.
PATCH /api/user0/comments/:id
Параметры
| Название | Описание |
|---|---|
body |
Обновлённый текст комментария |
body_format |
md или html, необязательный параметр, по умолчанию md |
Пример
curl https://www.loomio.com/api/user0/comments/123 \
-X PATCH \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"body": "updated comment",
"body_format": "md"
}'
Удаление комментария с сохранением записи
Удалите комментарий от имени пользователя, которому принадлежит API-ключ. Комментарий помечается как удалённый, его текст скрывается, но запись комментария сохраняется.
DELETE /api/user0/comments/:id
Пример
curl https://www.loomio.com/api/user0/comments/123 \
-X DELETE \
-H 'Authorization: Bearer YOUR_API_KEY'
Обсуждения
Создание обсуждения
Создаёт обсуждение от имени пользователя, которому принадлежит API-ключ.
POST /api/user0/discussions
Параметры
| Имя | Описание |
|---|---|
group_id |
Группа, в которой будет находиться ветка |
title |
Заголовок ветки, обязательный параметр |
description |
Описание ветки, необязательный параметр |
description_format |
md или html, необязательный параметр, по умолчанию md |
recipient_audience |
group или null. При значении group вся группа получит уведомление о новой ветке |
recipient_user_ids |
Массив идентификаторов пользователей, которых нужно уведомить или пригласить в ветку |
recipient_emails |
Массив адресов электронной почты людей, которых нужно пригласить в ветку |
recipient_message |
Сообщение для включения в приглашение по электронной почте |
Пример
curl https://www.loomio.com/api/user0/discussions \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"title": "example thread",
"recipient_emails": [
"person@example.com"
]
}'
Получение обсуждения
Получите обсуждение по его ID (целое число) или ключу (строка).
GET /api/user0/discussions/:id
Пример
curl https://www.loomio.com/api/user0/discussions/abc123 \
-H 'Authorization: Bearer YOUR_API_KEY'
Список обсуждений
Получите список обсуждений в группе, доступных пользователю, которому принадлежит API-ключ. Если группа общедоступна, человек, не состоящий в ней, может получить список её публичных обсуждений; закрытые обсуждения доступны только пользователям, которые могут читать их в Loomio.
GET /api/user0/discussions
Параметры
| Название | Описание |
|---|---|
group_id |
Целое число, обязательный параметр. ID группы, список обсуждений которой нужно получить |
status |
Строка, необязательный параметр, по умолчанию open. Значения: open, closed, all |
limit |
Целое число, необязательный параметр, по умолчанию 50. Размер страницы |
offset |
Целое число, необязательный параметр, по умолчанию 0. Смещение для постраничной выдачи |
Совместимость с прежними версиями: per и from принимаются как псевдонимы для limit и offset и продолжат работать.
Пример
curl 'https://www.loomio.com/api/user0/discussions?group_id=123' \
-H 'Authorization: Bearer YOUR_API_KEY'
Редактирование обсуждения
Отредактируйте обсуждение от имени пользователя, которому принадлежит API-ключ. Действуют те же права доступа, что и в Loomio: у пользователя должно быть право редактировать это обсуждение.
PATCH /api/user0/discussions/:id
Параметры
| Название | Описание |
|---|---|
title |
Обновлённый заголовок |
description |
Обновлённое описание |
description_format |
md или html, необязательный параметр, по умолчанию md |
recipient_audience |
group или null. Если указано group, вся группа получит уведомление об изменении |
recipient_user_ids |
Массив ID пользователей, которых нужно уведомить или пригласить в ветку |
recipient_emails |
Массив адресов электронной почты людей, которых нужно пригласить в ветку |
recipient_message |
Сообщение для включения в приглашение по электронной почте |
Пример
curl https://www.loomio.com/api/user0/discussions/123 \
-X PATCH \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"title": "updated thread title",
"description": "updated context",
"description_format": "md"
}'
Удаление обсуждения с сохранением записи
Удалите обсуждение от имени пользователя, которому принадлежит API-ключ. Обсуждение помечается как удалённое, но его запись сохраняется.
DELETE /api/user0/discussions/:id
Пример
curl https://www.loomio.com/api/user0/discussions/123 \
-X DELETE \
-H 'Authorization: Bearer YOUR_API_KEY'
Группы
Список групп
Возвращает группы, в которых пользователь, которому принадлежит API-ключ, является активным участником.
GET /api/user0/groups
| Имя | Описание |
|---|---|
limit |
Целое число, необязательный параметр, по умолчанию 50, максимум 500. Размер страницы |
offset |
Целое число, необязательный параметр, по умолчанию 0. Смещение для разбиения на страницы |
curl 'https://www.loomio.com/api/user0/groups?limit=50&offset=0' \
-H 'Authorization: Bearer YOUR_API_KEY'
Ответ содержит страницу записей groups, упорядоченных по возрастанию идентификатора группы, и общее количество подходящих групп в meta.total. В него входят родительские группы и подгруппы, в том числе группы, подписка которых сейчас неактивна. Проверяйте поле enabled, если интеграция должна работать только с активными группами.
Основные поля группы:
| Поле | Описание |
|---|---|
id |
Числовой идентификатор группы, используемый другими конечными точками пользовательского API |
key |
Постоянный короткий ключ, используемый в URL Loomio |
handle |
Человекочитаемый идентификатор группы |
name |
Название группы |
full_name |
Название группы с указанием родительской группы |
parent_id |
Числовой идентификатор родительской группы для подгруппы, в остальных случаях null |
enabled |
Активны ли группа и её подписка |
memberships_count |
Количество активных и ожидающих подтверждения записей об участии |
accepted_memberships_count |
Количество подтверждённых записей об участии |
pending_memberships_count |
Количество приглашений, ожидающих принятия |
admin_memberships_count |
Количество администраторов группы |
discussions_count |
Количество обсуждений непосредственно в группе |
polls_count |
Количество опросов непосредственно в группе |
subgroups_count |
Количество подгрупп |
Ответ может включать дополнительные настройки группы, связанные записи родительских групп и записи об участии пользователя API в группах. Клиентам следует игнорировать поля, которые они не используют.
Получение группы
Возвращает одну группу, доступную пользователю, которому принадлежит API-ключ.
GET /api/user0/groups/:id_or_key_or_handle
В качестве идентификатора можно использовать числовой идентификатор, ключ или человекочитаемый идентификатор группы.
curl https://www.loomio.com/api/user0/groups/123 \
-H 'Authorization: Bearer YOUR_API_KEY'
curl https://www.loomio.com/api/user0/groups/example-group \
-H 'Authorization: Bearer YOUR_API_KEY'
Ответ содержит группу в массиве groups и использует те же поля, что и конечная точка списка групп. Запрос группы, к которой у пользователя с API-ключом нет доступа, возвращает ошибку прав доступа.
Участники групп
Список участников группы
Получите список участников группы, доступный пользователю, которому принадлежит ключ API. Участники группы могут просматривать имена, идентификаторы, должности и роли участников. Адреса электронной почты включаются только для собственной учётной записи пользователя, которому принадлежит ключ API, или если этот пользователь является администратором группы.
GET /api/user0/memberships
Параметры
| Имя | Описание |
|---|---|
group_id |
Целое число, обязательный параметр. Идентификатор группы, список участников которой нужно получить |
limit |
Целое число, необязательный параметр, по умолчанию 50. Размер страницы |
offset |
Целое число, необязательный параметр, по умолчанию 0. Смещение для разбиения на страницы |
Для совместимости с прежними интеграциями per и from принимаются как альтернативные имена для limit и offset и продолжат работать.
Ответ содержит страницу записей memberships и связанные записи users. meta.total — общее количество доступных записей об участии в группе до разбиения на страницы.
Пример
curl 'https://www.loomio.com/api/user0/memberships?group_id=123&limit=50&offset=0' \
-H 'Authorization: Bearer YOUR_API_KEY'
Управление участниками группы
Отправьте список адресов электронной почты. На все новые адреса будут отправлены приглашения в группу. В отличие от получения списка участников, эта операция требует прав администратора группы.
POST /api/user0/memberships
Параметры
| Имя | Описание |
|---|---|
group_id |
Целое число, обязательный параметр. Идентификатор группы, составом участников которой нужно управлять |
emails |
Массив строк, обязательный параметр. Адреса электронной почты людей, которых нужно пригласить в группу |
remove_absent |
Логическое значение. Если true, из группы удаляются все, чьи адреса электронной почты отсутствуют в списке |
Пример
curl https://www.loomio.com/api/user0/memberships \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"emails": [
"person@example.com"
]
}'
Если вы передадите remove_absent=1, все участники группы, не включённые в список, будут удалены из группы. Будьте осторожны: вы можете удалить всех участников вашей группы.
curl https://www.loomio.com/api/user0/memberships \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"emails": [
"person@example.com"
],
"remove_absent": 1
}'
В ответ возвращается объект с {added_emails: ["person@added.com"], removed_emails: ["person@removed.com"]}.
Отчёт об участии
Возвращает те же сводные данные об участии, которые используются в отчёте об участии Loomio.
GET /api/user0/reports
Параметры
| Имя | Описание |
|---|---|
section |
Раздел отчёта: base, users или countries. Используйте users для активности отдельных пользователей |
group_scope |
custom или my. Устаревшее значение all трактуется как my, поскольку ключи пользовательского API никогда не предоставляют доступ ко всему экземпляру Loomio |
group_ids |
Идентификаторы групп через запятую при group_scope=custom. Идентификаторы групп, в которых пользователь API не состоит, игнорируются |
start_month |
Первый включаемый месяц в формате YYYY-MM; по умолчанию — месяц 12 месяцев назад |
end_month |
Последний включаемый месяц в формате YYYY-MM; по умолчанию — текущий месяц |
interval |
Интервал для раздела base: day, week, month или year |
member_type |
Укажите delegate вместе с section=users, чтобы получить только действующих делегатов |
Пользователь считается делегатом, если он является действующим участником с ролью делегата хотя бы в одной выбранной группе. Его показатели суммируются по всем выбранным группам. Строки делегатов возвращаются, даже если все показатели активности равны нулю. Показатели охватывают ветки, комментарии, опросы, голоса, выводы и реакции; они не отражают долю участия в голосовании. Строки пользователей также содержат число выданных, поданных и пропущенных именных бюллетеней. Анонимные опросы исключены из всех индивидуальных показателей голосования. Значение all_votes_cast равно true только в том случае, если был выдан хотя бы один бюллетень и все выданные бюллетени были поданы.
API применяет те же правила видимости групп, что и отчёт в приложении. API-ключ пользователя не может раскрыть данные отчёта из групп, к которым у этого пользователя нет доступа.
Пример
curl 'https://www.loomio.com/api/user0/reports?section=users&group_scope=custom&group_ids=123&member_type=delegate&start_month=2026-01&end_month=2026-09' \
-H 'Authorization: Bearer YOUR_API_KEY'
Массив users содержит строки со всеми показателями активности:
{
"users": [
{
"id": 456,
"name": "Ada Lovelace",
"country": "NZ",
"delegate": true,
"threads": 2,
"comments": 8,
"polls": 1,
"votes": 5,
"votes_cast": 5,
"votes_issued": 6,
"votes_missed": 1,
"all_votes_cast": false,
"outcomes": 1,
"reactions": 4
}
]
}
Опросы
Создание опроса
Создайте опрос от имени пользователя, которому принадлежит API-ключ.
POST /api/user0/polls
Параметры
| Название | Описание |
|---|---|
group_id |
Целое число, необязательно, по умолчанию null. ID группы для опроса. Если передан discussion_id, group_id игнорируется |
discussion_id |
Целое число, необязательно, по умолчанию null. ID ветки обсуждения, в которую нужно добавить этот опрос |
title |
Строка, обязательно. Заголовок опроса |
poll_type |
Строка, обязательно. Значения: proposal, poll, count, score, ranked_choice, meeting, dot_vote |
details |
Строка, необязательно. Основной текст опроса |
details_format |
Строка, необязательно, по умолчанию md. Значения: md или html |
options |
Простые названия вариантов в виде массива строк. Для proposal используйте agree, disagree, abstain или block, чтобы получить стандартные подписи, значки, значения и вопросы о причине выбора. Для meeting укажите строки с датой или датой и временем в формате ISO 8601. Для других типов опросов укажите названия вариантов. Для вариантов с подробными настройками используйте вместо этого poll_options_attributes |
poll_options_attributes |
Альтернатива options: массив объектов вариантов с названиями, значениями, вопросами, значками и порядком отображения. См. Создание опроса с подробными настройками вариантов |
reason_prompt |
Строка, необязательно. Общий вопрос о причине выбора для типов опросов без отдельных вопросов для каждого варианта, например poll, score и ranked_choice |
stance_reason_required |
Строка, по умолчанию optional. Значения: disabled, optional, required, required_for_disagree_or_block, required_for_block. Последние два значения применяются к значкам disagree и block. В анонимных опросах указание причин выбора отключено |
closing_at |
Строка в формате ISO 8601 или null, по умолчанию null. Пример: 2026-09-01T12:00:00Z. Если значение null, голосование отключено, а опрос считается находящимся в процессе подготовки |
specified_voters_only |
Логическое значение, необязательно, по умолчанию false. Если true, голосовать могут только указанные люди. Если false, все участники группы получат приглашение голосовать |
hide_results |
Строка, необязательно, по умолчанию off. Значения: off, until_vote, until_closed |
shuffle_options |
Логическое значение, по умолчанию false. Показывать варианты голосующим в случайном порядке |
anonymous |
Логическое значение, необязательно, по умолчанию false. Скрывать личности голосующих |
recipient_audience |
group или null, необязательно, по умолчанию null. Если group, вся группа получит уведомление |
notify_on_closing_soon |
Строка, необязательно, по умолчанию nobody. Значения: nobody, author, voters_uncast, voters |
recipient_user_ids |
Массив ID пользователей, которым нужно отправить уведомление или приглашение |
recipient_emails |
Массив адресов электронной почты людей, которых нужно пригласить голосовать |
recipient_message |
Сообщение для включения в приглашение по электронной почте |
notify_recipients |
Логическое значение, по умолчанию false. Если false, добавить людей без отправки уведомлений. Если true, все приглашённые в этом запросе получат уведомление по электронной почте |
Пример
curl https://www.loomio.com/api/user0/polls \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"title": "example poll",
"poll_type": "proposal",
"options": [
"agree",
"disagree"
],
"closing_at": "2026-09-01T12:00:00Z",
"recipient_emails": [
"person@example.com"
]
}'
Создание черновика опроса с большим количеством вариантов
Передайте все названия вариантов в массиве options. Если не указать closing_at, будет создан опрос в процессе подготовки с отключённым голосованием; при этом опрос останется видимым для людей, которым доступна его ветка. Когда вы будете готовы открыть голосование, укажите в closing_at дату и время в будущем.
Добавьте все названия ваших вариантов в массив:
curl https://www.loomio.com/api/user0/polls \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"title": "Meeting venue",
"poll_type": "poll",
"options": [
"Town hall",
"Library",
"Community centre"
]
}'
Создание опроса с подробными настройками вариантов
Используйте options для списка названий или poll_options_attributes, если каждому варианту нужно задать значение, вопрос о причине выбора или значок. Выберите один формат для каждого запроса. Оба формата работают как в плоском теле JSON, так и внутри объекта poll.
Каждый объект в poll_options_attributes принимает следующие поля:
| Поле | Описание |
|---|---|
name |
Строка, обязательна для нового варианта. Подпись, которую видят голосующие |
meaning |
Строка, необязательно. Объясняет, что означает выбор этого варианта |
prompt |
Строка, необязательно. Вопрос о причине выбора, который показывается при выборе этого варианта в proposal, count или check. Для других типов опросов задайте reason_prompt в самом опросе |
icon |
Строка, необязательно. Для proposal, count и check используйте agree, disagree, abstain или block |
priority |
Целое число. Порядок вариантов, начиная с 0. Укажите отдельное значение для каждого варианта; варианты времени встречи вместо этого упорядочиваются по дате |
test_operator |
Строка или null, необязательно. Требование к доле голосов: gte означает «не менее», lte — «не более». Укажите null, чтобы отключить требование |
test_percent |
Целое число, необязательно. Процент для требования к доле голосов, от 0 до 100 |
test_against |
Строка, необязательно. score_percent сравнивает долю варианта в общей сумме выставленных оценок или распределённых баллов; voter_percent сравнивает число выбравших этот вариант с общим числом людей, имеющих право голосовать |
id |
Целое число. Укажите при редактировании существующего варианта; не указывайте для нового варианта |
_destroy |
Логическое значение, необязательно. Укажите true вместе с id существующего варианта, чтобы удалить его |
Создайте предложение со своими подписями вариантов и вопросами:
curl https://www.loomio.com/api/user0/polls \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"title": "Should we adopt this proposal?",
"poll_type": "proposal",
"stance_reason_required": "optional",
"poll_options_attributes": [
{
"name": "Support",
"meaning": "I support adopting this proposal",
"prompt": "What do you support about it?",
"icon": "agree",
"priority": 0
},
{
"name": "Oppose",
"meaning": "I would prefer another approach",
"prompt": "What would you change?",
"icon": "disagree",
"priority": 1
}
]
}'
Для обычного опроса используйте тот же формат подробных настроек вариантов с общим вопросом reason_prompt в самом опросе:
curl https://www.loomio.com/api/user0/polls \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"title": "Choose a venue",
"poll_type": "poll",
"reason_prompt": "Why do you prefer this venue?",
"stance_reason_required": "optional",
"poll_options_attributes": [
{
"name": "Town hall",
"meaning": "Central, accessible venue",
"priority": 0
},
{
"name": "Library",
"meaning": "Smaller room with no hire fee",
"priority": 1
}
]
}'
В этих примерах closing_at не указан, поэтому голосование остаётся отключённым, пока не будет установлена дата закрытия в будущем.
Получение опроса
Получите опрос по его ID (целому числу) или ключу (строке).
GET /api/user0/polls/:id
Пример
curl https://www.loomio.com/api/user0/polls/abc123 \
-H 'Authorization: Bearer YOUR_API_KEY'
Список опросов
Получите список опросов в группе, доступных пользователю, которому принадлежит API-ключ, включая отдельные опросы и опросы внутри обсуждений. Если группа общедоступна, пользователь, не состоящий в ней, может получить список её общедоступных опросов; доступ к закрытым от посторонних опросам имеют только пользователи, которые могут читать их в Loomio. Ответ включает текущий вывод каждого доступного опроса, поэтому вы можете использовать status=closed, чтобы получить список закрытых опросов и прочитать их выводы, если они были указаны.
Чтобы отображать статус решения рядом с обсуждениями, получите обсуждения и опросы одной группы, используя status=all для опросов, и сопоставьте их значения topic_id. Получите все страницы с помощью limit и offset. В обсуждении может быть несколько опросов, поэтому выберите, какой опрос определяет отображаемый статус, например последний созданный опрос. Значение closed_at, отличное от null, указывает на закрытый опрос; значение null в closing_at указывает на черновик. Если у опроса есть вывод, его current_outcome_id указывает на запись в массиве outcomes в ответе; сопоставьте poll_id этой записи с id опроса.
Для отдельного обсуждения вы также можете прочитать элементы его ветки с помощью GET /api/user0/threads/:topic_id/items. Ответ содержит опросы и выводы ветки вместе с другими её элементами. Получите все страницы, чтобы включить ветку целиком.
GET /api/user0/polls
Параметры
| Название | Описание |
|---|---|
group_id |
Целое число, обязательный параметр. ID группы, из которой нужно получить список опросов |
status |
Строка, необязательный параметр, по умолчанию active. Значения: active, closed, all |
limit |
Целое число, необязательный параметр, по умолчанию 50. Размер страницы |
offset |
Целое число, необязательный параметр, по умолчанию 0. Смещение для постраничного вывода |
Для совместимости с прежними версиями per и from принимаются как синонимы limit и offset и продолжат работать.
Пример
curl 'https://www.loomio.com/api/user0/polls?group_id=123' \
-H 'Authorization: Bearer YOUR_API_KEY'
Редактирование опроса
Отредактируйте опрос от имени пользователя, которому принадлежит API-ключ. Действуют те же права доступа, что и в Loomio: пользователь должен иметь право редактировать этот опрос.
PATCH /api/user0/polls/:id
Параметры
| Название | Описание |
|---|---|
title |
Обновлённый заголовок |
details |
Обновлённое описание опроса |
details_format |
md или html, необязательно, по умолчанию md |
options |
Обновлённые названия вариантов. Изменение вариантов может повлиять на существующие голоса в зависимости от состояния опроса |
poll_options_attributes |
Альтернатива options. Обновите объекты с подробными настройками вариантов по id, добавьте объекты без id или удалите вариант, указав id и _destroy: true. Варианты, не включённые в запрос, остаются без изменений |
reason_prompt |
Обновлённый общий вопрос о причине выбора для типов опросов без отдельных вопросов для каждого варианта |
stance_reason_required |
Обновлённое требование к указанию причины выбора; допустимы те же значения, что и при создании опроса |
closing_at |
Строка в формате ISO 8601 или null |
recipient_audience |
group или null. Если group, вся группа получит уведомление |
recipient_user_ids |
Массив ID пользователей, которым нужно отправить уведомление или приглашение |
recipient_emails |
Массив адресов электронной почты людей, которых нужно пригласить голосовать |
recipient_message |
Сообщение для включения в приглашение по электронной почте |
Пример
curl https://www.loomio.com/api/user0/polls/123 \
-X PATCH \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"title": "updated poll title",
"details": "updated details",
"details_format": "md"
}'
Редактирование подробных настроек вариантов
Получите ID вариантов из массива poll_options в ответе на запрос создания или получения опроса. Передайте только поля, которые нужно изменить, вместе с id каждого существующего варианта:
curl https://www.loomio.com/api/user0/polls/123 \
-X PATCH \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"poll_options_attributes": [
{
"id": 456,
"meaning": "Updated explanation",
"prompt": "What would improve this proposal?"
},
{
"name": "Abstain",
"meaning": "I leave the decision to others",
"icon": "abstain",
"priority": 2
}
]
}'
ID вариантов должны принадлежать редактируемому опросу. Для редактирования требуется разрешение на изменение опроса; закрытые опросы редактировать нельзя. В анонимных опросах настройки вариантов также нельзя изменять после подачи первого голоса.
Мягкое удаление опроса
Выполните мягкое удаление опроса от имени пользователя, которому принадлежит API-ключ. Опрос помечается как удалённый, а его запись сохраняется.
DELETE /api/user0/polls/:id
Пример
curl https://www.loomio.com/api/user0/polls/123 \
-X DELETE \
-H 'Authorization: Bearer YOUR_API_KEY'
Поиск
Поиск обсуждений, комментариев, опросов, голосов и выводов, доступных пользователю, которому принадлежит API-ключ. Результаты включают публичное содержимое, даже если пользователь не является участником соответствующей группы; доступ к закрытому содержимому определяется обычными правилами видимости веток.
GET /api/user0/search
Параметры
| Имя | Описание |
|---|---|
query |
Текст для поиска. Поддерживаются точные и приблизительные совпадения |
group_id |
Ограничивает результаты одной доступной группой |
org_id |
Ограничивает результаты доступной родительской группой и её доступными подгруппами. Используйте 0 для прямых обсуждений |
type |
Ограничивает результаты одним типом: Discussion, Comment, Poll, Stance или Outcome |
types |
Список типов результатов через запятую |
tag |
Ограничивает результаты ветками с этим тегом |
author_id |
Ограничивает результаты содержимым одного автора. Без query возвращает недавнюю доступную активность этого автора |
order |
Укажите authored_at_desc, чтобы упорядочить найденное содержимое по времени создания |
curl 'https://www.loomio.com/api/user0/search?query=quarterly+planning&type=Discussion' \
-H 'Authorization: Bearer YOUR_API_KEY'
Ответ содержит массив search_results. Каждый результат указывает на найденную запись и доступные сведения о ней с помощью полей, включая searchable_type, searchable_id, highlight, group_id, group_name, discussion_key, poll_key, author_id, author_name, authored_at и tags. Поля, неприменимые к результату, имеют значение null.
Ветки
Список веток
Получите список веток обсуждений и опросов, доступных пользователю, которому принадлежит API-ключ, в порядке последней активности. ID ветки — это её topic_id.
GET /api/user0/threads
Параметры
| Название | Описание |
|---|---|
limit |
Целое число, необязательный параметр, по умолчанию 50. Размер страницы |
offset |
Целое число, необязательный параметр, по умолчанию 0. Смещение для постраничной выдачи |
Пример
curl 'https://www.loomio.com/api/user0/threads?limit=50&offset=0' \
-H 'Authorization: Bearer YOUR_API_KEY'
Чтение ветки
Получите ветку, её упорядоченную последовательность событий или полное доступное содержимое в виде документа Markdown.
GET /api/user0/threads/:topic_id
GET /api/user0/threads/:topic_id/items
GET /api/user0/threads/:topic_id/markdown
Конечная точка items принимает следующие параметры постраничной выдачи:
| Название | Описание |
|---|---|
limit |
Целое число, необязательный параметр, по умолчанию 50, максимум 500. Размер страницы |
offset |
Целое число, необязательный параметр, по умолчанию 0. Смещение для постраничной выдачи |
Пример
GET https://www.loomio.com/api/user0/threads/<topic_id>
GET https://www.loomio.com/api/user0/threads/<topic_id>/items?limit=50&offset=0
GET https://www.loomio.com/api/user0/threads/<topic_id>/markdown
Конечная точка items возвращает страницу последовательности событий в порядке возрастания их порядковых номеров, включая доступные комментарии, опросы, голоса и выводы. meta.total — общее количество элементов в ветке. Запросите следующие страницы, чтобы прочитать всю последовательность. Конечная точка markdown возвращает полное доступное содержимое ветки в виде одного документа Markdown. Причины выбора включаются только тогда, когда они доступны пользователю, которому принадлежит API-ключ.
Все конечные точки для веток применяют те же права доступа, что и интерфейс Loomio. API-ключ не предоставляет доступ к ветке, которую пользователь не может открыть обычным способом.
Вебхуки
Пользовательский API работает на основе запросов: интеграция обращается к Loomio, когда ей нужно прочитать или изменить данные. Вебхук группы позволяет отправлять данные в обратном направлении. Loomio отправляет выбранные события группы на вашу конечную точку по мере их возникновения, поэтому интеграции не нужно регулярно опрашивать REST API для обнаружения изменений.
Вебхуки настраиваются отдельно для каждой группы и требуют прав администратора группы. Ими можно управлять через интерфейс Loomio:
- Откройте группу.
- Откройте меню группы и выберите Интеграция чата.
- Добавьте интеграцию, соответствующую формату данных, который принимает ваша конечная точка. Для конечной точки общего назначения используйте формат Mattermost/Markdown.
- Введите название и URL назначения.
- Выберите события, которые Loomio должен отправлять автоматически.
- Сохраните интеграцию и используйте Тестовое соединение, чтобы отправить тестовое сообщение.
Используйте HTTPS и URL назначения, который невозможно угадать. Loomio требует, чтобы адрес назначения разрешался в публичный адрес, и блокирует запросы к локальным адресам и адресам частных сетей.
Агенты и другие интеграции могут управлять вебхуками через описанные ниже конечные точки чат-ботов с аутентификацией Bearer. Ресурс называется chatbots для совместимости с интеграциями чата Loomio, но также представляет исходящие вебхуки общего назначения.
Список вебхуков
Возвращает интеграции чата, настроенные для группы. Пользователь, которому принадлежит API-ключ, должен быть администратором этой группы. Ответ включает URL назначения, поэтому его нельзя раскрывать обычным участникам группы.
GET /api/user0/chatbots?group_id=123
| Название | Описание |
|---|---|
group_id |
Целое число, обязательный параметр. ID группы, вебхуки которой нужно перечислить |
limit |
Целое число, необязательный параметр, по умолчанию 50, максимум 500. Размер страницы |
offset |
Целое число, необязательный параметр, по умолчанию 0. Смещение для постраничной выдачи |
curl 'https://www.loomio.com/api/user0/chatbots?group_id=123&limit=50&offset=0' \
-H 'Authorization: Bearer YOUR_API_KEY'
Ответ содержит страницу chatbots, упорядоченную по возрастанию ID интеграции, и общее количество интеграций в группе в meta.total. Каждая интеграция содержит следующие поля:
| Поле | Описание |
|---|---|
id |
Идентификатор интеграции, используемый для обновления и удаления |
group_id |
Группа, получающая события |
name |
Название интеграции для администрирования |
kind |
webhook для исходящего вебхука или matrix для интеграции с Matrix |
webhook_kind |
Формат данных: markdown, slack, discord, microsoft или webex |
server |
URL назначения |
event_kinds |
События, отправляемые автоматически |
notification_only |
Содержат ли сообщения только заголовок уведомления |
Создание вебхука
POST /api/user0/chatbots
curl https://www.loomio.com/api/user0/chatbots \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"name": "Planning system",
"kind": "webhook",
"webhook_kind": "markdown",
"server": "https://hooks.example.org/loomio/unguessable-token",
"event_kinds": [
"new_discussion",
"new_comment",
"poll_created",
"outcome_created"
],
"notification_only": false
}'
Пользователь, которому принадлежит API-ключ, должен быть администратором группы с идентификатором group_id. Перед сохранением проверяется, что URL назначения является публичным.
Обновление вебхука
PATCH /api/user0/chatbots/:id
Передайте поля, которые нужно изменить. Вебхук нельзя перенести в другую группу, изменив group_id.
curl https://www.loomio.com/api/user0/chatbots/456 \
-X PATCH \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"name": "Planning events",
"event_kinds": [
"new_discussion",
"outcome_created"
]
}'
Проверка адреса назначения вебхука
Отправьте тестовое сообщение в формате, совместимом с Markdown, на адрес назначения до или после сохранения его конфигурации.
POST /api/user0/chatbots/check
curl https://www.loomio.com/api/user0/chatbots/check \
-H 'Authorization: Bearer YOUR_API_KEY' \
--json '{
"group_id": 123,
"server": "https://hooks.example.org/loomio/unguessable-token"
}'
Удаление вебхука
DELETE /api/user0/chatbots/:id
curl https://www.loomio.com/api/user0/chatbots/456 \
-X DELETE \
-H 'Authorization: Bearer YOUR_API_KEY'
Удаление конфигурации прекращает дальнейшую отправку сообщений. Содержимое группы Loomio при этом не удаляется.
Типы событий
Вебхук может подписаться на следующие типы событий:
| Событие | Когда отправляется |
|---|---|
new_discussion |
Начато обсуждение |
discussion_edited |
Обсуждение отредактировано |
new_comment |
Создан комментарий |
poll_created |
Начат опрос |
poll_edited |
Опрос отредактирован |
poll_closing_soon |
Приближается время закрытия опроса |
poll_expired |
Наступило время закрытия опроса |
poll_closed_by_user |
Пользователь закрыл опрос вручную |
poll_reopened |
Голосование в опросе возобновлено |
outcome_created |
Опубликован вывод |
outcome_updated |
Вывод обновлён |
outcome_review_due |
Наступил срок пересмотра вывода |
stance_created |
Подан голос |
stance_updated |
Голос изменён |
Вебхук принадлежит одной группе и получает события этой группы, на которые он подписан. Пользователи также могут явно выбрать интеграцию, когда делятся содержимым или отправляют некоторые уведомления, даже если соответствующее автоматическое событие не выбрано.
Доставка по HTTP
Loomio асинхронно отправляет HTTP-запрос POST на настроенный URL с таким заголовком:
Content-Type: application/json; charset=utf-8
Время ожидания ответа на запрос составляет пять секунд. Ответ 2xx, включая 204 No Content, считается успешным. Получатели вебхуков должны отвечать быстро, выполнять длительную обработку асинхронно и учитывать возможность повторной доставки или доставки не по порядку.
В настоящее время Loomio не добавляет подпись вебхука, заголовок с общим секретом, идентификатор события или идентификатор доставки. Обращайтесь с полным URL назначения как с учётными данными, не публикуйте его и включайте в URL токен, который невозможно угадать, если принимающий сервис это поддерживает. Если требуется стабильная машиночитаемая схема событий или доставка с подписью, используйте вебхук как уведомление об изменении и получайте актуальные записи через пользовательский API с аутентификацией.
Форматы передаваемых данных
Данные вебхуков — это сообщения для отображения в чатах. Они не являются полными сериализованными записями Loomio. Ссылки в сообщении указывают на затронутое содержимое Loomio; если интеграции нужны структурированные данные о текущем состоянии, она может дополнительно запросить их через пользовательский API.
| Формат интеграции | Основные поля JSON |
|---|---|
| Mattermost/Markdown | text, icon_url, username |
| Slack | text |
| Discord | content, ограничено примерно 1 900 символами |
| Microsoft Teams | @type, @context, themeColor, text, sections |
| Webex | markdown |
Например, общий формат Markdown отправляет тело запроса следующего вида:
{
"text": "Ada started a discussion: [Quarterly planning](https://example.loomio.org/d/example)",
"icon_url": "https://example.loomio.org/path/to/group-logo.png",
"username": "Loomio"
}
Точный текст сообщения зависит от события, языка группы, настройки отправки только уведомлений и версии Loomio. Получателям следует использовать документированные поля верхнего уровня выбранного формата, а не разбирать формулировки предложений.