Loomio 사용자 API 문서
/api/user0은 Loomio 연동을 위한 사용자 중심 API입니다. 사용자 계정의 API 키를 사용하며, 모든 작업은 해당 사용자로 수행됩니다.
그룹 작업에는 API 키 사용자의 멤버십과 그룹 권한이 적용됩니다. 인스턴스 관리자 지위가 있어도 API 키로 접근할 수 있는 그룹이나 콘텐츠의 범위는 확대되지 않습니다. 인스턴스 수준의 관리에는 서버 API를 사용하세요.
작업을 수행할 Loomio 사용자 계정의 API 키를 사용하세요. 연동 계정이 투표에 초대되거나 알림을 받지 않아야 하는 경우에는 전용 봇 계정이 유용합니다.
로그인한 사용자는 API 접근 페이지에서 API 키와 그룹 ID를 확인할 수 있습니다.
API 키는 Authorization: Bearer 헤더로 보내세요. URL이 프록시나 접근 로그에 기록될 수 있으므로 쿼리 문자열에 포함된 API 키는 거부됩니다.
Authorization: Bearer YOUR_API_KEY
예제에서는 YOUR_API_KEY, 그룹 ID 123, https://www.loomio.com/을 사용합니다. 이를 사용할 API 키, 그룹 ID, Loomio 설치 URL로 바꾸세요.
요청 본문 보내기
Content-Type: application/json으로 JSON을 보내세요. cURL 예제에서는 이 헤더를 자동으로 설정하는 --json을 사용합니다. 토론, 댓글, 투표의 생성 및 편집 엔드포인트는 평면 객체 또는 {"poll": {...}}처럼 리소스 이름 아래에 중첩된 객체를 받습니다.
배열은 "options": ["foo", "bar"]처럼 JSON 배열로 보내세요. 대신 폼 인코딩을 사용하는 경우에는 options[]=foo&options[]=bar처럼 필드 이름에 대괄호를 붙여야 합니다. options=foo&options=bar처럼 반복하면 마지막 값만 유지됩니다.
각 요청 후에 HTTP 상태와 응답 본문을 확인하세요. 유효성 검사에 실패하면 errors 객체와 함께 422가 반환됩니다. 투표 생성에 성공하면 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와 from도 각각 limit과 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을 적용하기 전에 계산됩니다. 검색처럼 의도적으로 제한된 결과 집합을 반환하는 엔드포인트는 null을 반환하는 대신 meta.total을 생략합니다.
댓글
댓글 생성
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 |
알림을 보내거나 스레드에 초대할 사용자 ID 배열 |
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'
응답에는 그룹 ID 오름차순으로 정렬된 groups의 한 페이지가 포함되며, 조건에 맞는 전체 그룹 수는 meta.total에 포함됩니다. 상위 그룹과 하위 그룹이 포함되며, 현재 구독이 활성 상태가 아닌 그룹도 포함됩니다. 연동이 활성화된 그룹에서만 작동해야 한다면 enabled 필드를 확인하세요.
주요 그룹 필드는 다음과 같습니다.
| 필드 | 설명 |
|---|---|
id |
다른 사용자 API 엔드포인트에서 사용하는 숫자형 그룹 ID |
key |
Loomio URL에서 사용하는 고정된 짧은 키 |
handle |
사람이 읽기 쉬운 그룹 핸들 |
name |
그룹 이름 |
full_name |
상위 그룹 정보를 포함한 그룹 이름 |
parent_id |
하위 그룹이면 숫자형 상위 그룹 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
식별자로 그룹의 숫자형 ID, 키 또는 핸들을 사용할 수 있습니다.
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 키 사용자가 볼 수 있는 멤버 자격 목록을 조회합니다. 그룹 멤버는 멤버의 이름, ID, 직함, 역할을 읽을 수 있습니다. 이메일 주소는 API 키 사용자 본인의 계정이거나 API 키 사용자가 그룹 관리자인 경우에만 포함됩니다.
GET /api/user0/memberships
매개변수
| 이름 | 설명 |
|---|---|
group_id |
정수. 필수 사항입니다. 멤버 자격 목록을 조회할 그룹의 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 |
정수, 필수. 멤버십을 관리할 그룹의 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. 사용자 API 키에는 인스턴스 전체에 대한 접근 권한이 부여되지 않으므로 기존 all 값은 my로 처리됩니다 |
group_ids |
group_scope=custom일 때 쉼표로 구분한 그룹 ID입니다. API 사용자가 멤버십을 보유하지 않은 그룹의 ID는 무시됩니다 |
start_month |
포함할 첫 번째 월이며 YYYY-MM 형식입니다. 기본값은 12개월 전입니다 |
end_month |
포함할 마지막 월이며 YYYY-MM 형식입니다. 기본값은 이번 달입니다 |
interval |
base 섹션의 집계 간격: day, week, month, year |
member_type |
현재 대표자만 반환하려면 section=users와 함께 delegate로 설정하세요 |
선택한 그룹 중 하나라도 활성 대표자 멤버십을 보유한 사람은 대표자로 간주됩니다. 활동 수는 선택한 모든 그룹에 걸쳐 집계됩니다. 모든 활동 수가 0이어도 대표자 행은 반환됩니다. 집계 대상은 스레드, 댓글, 투표, 표, 결론, 반응이며, 투표 참여율을 나타내지는 않습니다. 사용자 행에는 신원이 확인되는 투표에서 발급된 투표용지 수, 제출된 투표용지 수, 제출되지 않은 투표용지 수도 포함됩니다. 익명 투표는 모든 개인별 투표 집계에서 제외됩니다. 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 |
불리언, 선택 사항. 기존 선택지의 id와 함께 true로 설정하면 해당 선택지를 제거합니다 |
사용자 지정 선택지 레이블과 안내 문구로 제안을 생성하세요.
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를 사용하면 마감된 투표 목록을 조회하고 결론이 작성된 경우 이를 읽을 수 있습니다.
토론과 함께 결정 상태를 표시하려면 같은 그룹의 토론과 투표를 가져온 다음 topic_id 값을 대조하세요. 투표를 가져올 때는 status=all을 사용하세요. limit와 offset을 사용해 모든 페이지를 가져오세요. 하나의 토론에 여러 투표가 있을 수 있으므로, 가장 최근에 생성된 투표 등 표시할 상태의 기준이 되는 투표를 선택하세요. closed_at이 null이 아니면 마감된 투표이고, closing_at이 null이면 초안입니다. 투표에 결론이 있으면 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"
}'
상세 선택지 수정
생성 또는 조회 응답의 poll_options 배열에서 선택지 ID를 확인하세요. 변경할 필드만 각 기존 선택지의 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가 자동으로 전송할 이벤트를 선택하세요.
- 연동을 저장하고 연결 테스트로 테스트 메시지를 보내세요.
추측하기 어려운 URL을 가진 HTTPS 대상을 사용하세요. Loomio는 대상 주소가 공개 주소로 해석되어야 하며, 로컬 또는 사설 네트워크 주소로 향하는 요청은 허용하지 않습니다.
에이전트나 다른 연동 서비스는 아래에 설명된 Bearer 인증 방식의 챗봇 엔드포인트로 웹훅을 관리할 수도 있습니다. 리소스 이름은 Loomio의 채팅 연동과의 호환성을 위해 chatbots로 지정되어 있지만, 일반적인 발신 웹훅도 나타냅니다.
웹훅 목록 조회
그룹에 설정된 채팅 연동을 반환합니다. 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'
응답에는 연동 ID의 오름차순으로 정렬된 chatbots 페이지가 포함되며, meta.total에는 해당 그룹의 전체 연동 수가 포함됩니다. 각 연동에는 다음 필드가 있습니다.
| 필드 | 설명 |
|---|---|
id |
수정 및 삭제에 사용하는 연동 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
요청 제한 시간은 5초입니다. 204 No Content를 포함한 2xx 응답은 성공으로 처리됩니다. 웹훅 수신 측은 신속하게 응답하고, 오래 걸리는 작업은 비동기로 처리하며, 중복되거나 순서가 뒤바뀐 전송을 처리할 수 있어야 합니다.
현재 Loomio는 웹훅 서명, 공유 비밀 헤더, 이벤트 ID 또는 전송 ID를 추가하지 않습니다. 전체 대상 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 버전에 따라 달라집니다. 수신 측은 문장의 표현을 분석하기보다 선택한 형식의 문서에 명시된 최상위 필드를 사용해야 합니다.