REST API
Antimatter 앱이 수행하는 모든 작업은 동일한 HTTP API를 통해 이루어지므로, 스크립트도 이를 사용할 수 있습니다. 이 페이지에서는 인증 방법, 가장 많이 사용하는 리소스, 응답과 오류의 형식, 그리고 WebSocket을 통해 실시간으로 이벤트를 추적하는 방법을 설명합니다.
기본 사항
- 기본 URL:
https://chat.example.com/api/v4. 아래에 나열된 모든 엔드포인트는 이 URL을 기준으로 합니다. - 형식: 파일 업로드(multipart)를 제외하고는 입력과 출력 모두 JSON 형식입니다.
Content-Type: application/json을 보내야 합니다. - ID: 모든 객체는 26자리의
id를 가집니다. 시간은 Unix epoch 기준 밀리초 단위입니다(create_at,update_at,delete_at; 0은 "삭제되지 않음"을 의미합니다). - 커뮤니티는 팀입니다: API에서는 이를
teams라고 부르며,team_id를 사용합니다. - 당신:
user_id를 받는 경로에서me는 로그인한 사용자를 의미하며,GET /users/me와 같습니다.
엔드포인트 전체 목록은 서버 코드에 있습니다. 라우트는 server/channels/api4/*.go에, 타입은 server/public/model에 선언되어 있습니다. 저장소의 api/v4/source 폴더에 있는 OpenAPI 설명은 Mattermost에서 상속된 엔드포인트와 Antimatter의 일부 추가 기능(글타래 이동, 모델 연결, 메시지 작업)을 다룹니다. 나머지는 코드에만 있습니다.
인증
로그인 및 일부 공개 엔드포인트를 제외한 모든 요청에는 Authorization 헤더에 토큰이 필요합니다:
curl -H "Authorization: Bearer $TOKEN" https://chat.example.com/api/v4/users/me
여기서 세 가지 유형의 토큰이 허용됩니다: 개인 액세스 토큰, 세션 토큰, OAuth 액세스 토큰. Authorization: Token … 형식도 허용됩니다. 쿼리 문자열(?access_token=)에 포함된 토큰은 OAuth 액세스 토큰에 대해서만 허용됩니다.
개인 액세스 토큰(스크립트 사용 권장)
개인 액세스 토큰은 사용자를 대신하여 작동하며, 만료일을 지정하지 않는 한 만료되지 않고, 언제든지 폐기할 수 있습니다. 개인 액세스 토큰은 기본적으로 비활성화되어 있습니다:
- 시스템 관리자가 시스템 콘솔 › 통합 › 통합관리에서 개인 액세스 토큰을 활성화합니다(
ServiceSettings.EnableUserAccessTokens,AM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS). - 토큰을 생성할 수 있는 각 사용자를 위해, 시스템 관리자는 시스템 콘솔 › 사용자 관리 › 사용자를 열고 해당 사용자의 메뉴에서 역할 관리를 선택한 뒤 이 계정이 개인 액세스 토큰을 생성할 수 있도록 허용을 선택합니다. 시스템 관리자는 항상 토큰을 생성할 수 있습니다.
- 사용자는 오른쪽 위 아바타를 연 다음 프로필 & 설정 › 보안으로 이동합니다. 개인 액세스 토큰 아래에서 토큰의 용도를 설명하고 토큰 생성하기를 선택합니다. 토큰은 한 번만 표시됩니다: 복사해 두세요.
API를 사용하는 경우: POST /users/{user_id}/tokens에 {"description": "backup script", "expires_at": 0}를 전달합니다 (expires_at는 밀리초 단위이며, 0이면 만료 없음). 응답의 token 필드가 시크릿이며, id는 토큰을 폐기할 때 사용합니다 (POST /users/tokens/revoke에 {"token_id": "…"}를 전달). 명령줄에서는: amctl token generate <user> <description>를 사용합니다.
시스템 관리자는 같은 시스템 콘솔 페이지의 개인 액세스 토큰 최대 유효 기간(일)으로 토큰 유효 기간을 제한할 수 있습니다.
세션 토큰
비밀번호로 로그인하면 Token 응답 헤더에 세션 토큰이 반환됩니다. 이는 앱이 사용하는 것과 동일한 종류의 세션입니다:
curl -i -X POST https://chat.example.com/api/v4/users/login \
-H 'Content-Type: application/json' \
-d '{"login_id": "maya", "password": "…"}'
다중 인증을 사용하는 계정의 경우 "token": "123456"을 추가합니다. 세션은 서버의 세션 설정에 따라 만료되며, 로그인 엔드포인트는 속도 제한이 적용됩니다(초당 5개 요청). POST /users/logout를 호출하면 세션이 종료됩니다.
X-CSRF-Token 헤더를 함께 전송해야 합니다. Authorization 헤더에 포함된 토큰은 CSRF 헤더가 필요 없습니다.OAuth 2.0 앱
사용자가 Antimatter 계정으로 애플리케이션에 로그인할 수 있도록 하려면 OAuth 2.0 앱을 등록합니다. 그러면 Antimatter가 OAuth 제공자가 됩니다:
- OAuth 2.0 서비스 제공자가 켜져 있어야 합니다(시스템 콘솔 › 통합 › 통합관리,
ServiceSettings.EnableOAuthServiceProvider, 기본적으로 켜져 있음). - OAuth 앱 관리 권한이 있는 사용자(기본적으로 시스템 관리자)는 아바타를 열고 통합 › OAuth 2.0 앱으로 이동한 뒤 콜백 URL과 함께 앱을 추가합니다. 그러면 클라이언트 ID와 클라이언트 시크릿을 받게 됩니다.
- 애플리케이션은
response_type=code,client_id,redirect_uri및state와 함께 사용자를https://chat.example.com/oauth/authorize로 이동시킵니다.code_challenge_method=S256를 사용한 PKCE가 지원됩니다. POST https://chat.example.com/oauth/access_token에서 코드를 교환합니다(grant_type=authorization_code, 이후refresh_token으로 갱신)하고,Authorization: Bearer <access token>를 사용하여 API를 호출합니다.
사용자는 프로필 및 설정 › 보안 › 승인한 앱에서 승인한 앱을 볼 수 있습니다.
주요 리소스
| 항목 | 엔드포인트 |
|---|---|
| 나와 다른 사용자 | GET /users/me, GET /users/{user_id}, GET /users/username/{username}, POST /users/ids(ID 목록), POST /users/search, GET /users?in_team=…&in_channel=… |
| 커뮤니티 | GET /users/me/teams, GET /teams/{team_id}, GET /teams/name/{name}, PUT /teams/{team_id}/patch, GET /teams/{team_id}/members, POST /teams/{team_id}/members |
| 채널 | GET /users/me/teams/{team_id}/channels, GET /teams/name/{team}/channels/name/{channel}, POST /channels, POST /channels/direct(두 사용자 ID), POST /channels/group, POST /channels/{channel_id}/members |
| 메시지(게시물) | POST /posts, GET /posts/{post_id}, PUT /posts/{post_id}/patch, DELETE /posts/{post_id}, GET /channels/{channel_id}/posts, GET /posts/{post_id}/thread, POST /teams/{team_id}/posts/search |
| 반응 | {"user_id", "post_id", "emoji_name"}와 함께 POST /reactions, DELETE /users/{user_id}/posts/{post_id}/reactions/{emoji_name} |
| 파일 | POST /files(멀티파트: channel_id 및 files), 이후 반환된 ID를 게시물의 file_ids에 넣습니다. GET /files/{file_id} |
| 환경 설정 | GET /users/me/preferences, PUT /users/me/preferences |
| 통합 | /hooks/incoming, /hooks/outgoing, /commands, /bots, /oauth/apps(다음 페이지 참조) |
| 서버 | GET /system/ping(상태 확인, 토큰 불필요), GET /config/client?format=old(클라이언트가 보는 설정) |
메시지 게시
curl -X POST https://chat.example.com/api/v4/posts \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"channel_id": "'$CHANNEL_ID'", "message": "Backup finished: **42 GB** in 3 min"}'
메시지는 Markdown 형식입니다. 글타래에 답글을 달려면 "root_id"(글타래의 첫 게시물)를, 파일을 첨부하려면 "file_ids"를, 첨부 파일 및 기타 추가 정보를 위해 "props"를 사용합니다(첨부 파일 참조).
채널 ID 찾기
curl -H "Authorization: Bearer $TOKEN" \
https://chat.example.com/api/v4/teams/name/lumen-labs/channels/name/ops-alerts
이름은 채널 링크에 있는 것입니다: /lumen-labs/channels/ops-alerts.
페이지네이션
목록 엔드포인트는 page(0부터)와 per_page(기본값 60, 최대 200)를 받습니다. per_page보다 짧은 페이지가 반환될 때까지 다음 페이지를 계속 요청합니다.
채널의 메시지(GET /channels/{channel_id}/posts)도 since(시간: 그 이후에 변경된 모든 것) 또는 before와 after(게시물 ID)를 받습니다. 게시글 목록으로 반환됩니다: {"order": [IDs, newest first], "posts": {ID: post}, "next_post_id", "prev_post_id"}.
오류
오류는 일반적인 HTTP 상태 코드(400 잘못된 입력, 401 로그인 안 됨, 403 권한 없음, 404 찾을 수 없음, 501 기능 비활성화)와 JSON 본문으로 반환됩니다:
{
"id": "api.context.permissions.app_error",
"message": "You do not have the appropriate permissions.",
"detailed_error": "",
"request_id": "jz8zm5nunpbt8f3gpqsz5dq6so",
"status_code": 403
}
코드에서는 id를 사용하세요: message는 사용자의 언어로 번역됩니다. detailed_error는 서버가 개발자 모드(ServiceSettings.EnableDeveloper)로 실행되지 않는 한 비어 있습니다. request_id를 서버 관리자에게 인용하세요: 로그에 있습니다.
요청 제한
속도 제한은 기본적으로 꺼져 있습니다. 시스템 관리자가 활성화하면(시스템 콘솔 › 환경 › 속도 제한), 기본적으로 각 클라이언트는 초당 10개 요청, 최대 100개 버스트를 허용받으며 IP 주소 또는 사용자별로 계산됩니다. 응답에는 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset가 포함되며, 한도를 초과하면 서버는 429와 함께 초 단위의 Retry-After 헤더로 응답합니다. 로그인과 같은 일부 엔드포인트는 설정과 관계없이 자체 한도가 적용됩니다.
429 발생 시 대기하고 재시도하는 스크립트를 작성하고, 폴링을 피하세요: 대신 WebSocket을 따르세요.
WebSocket 이벤트 스트림
wss://chat.example.com/api/v4/websocket에 연결하세요. 연결 요청에 Authorization: Bearer 헤더를 사용하여 인증하거나, 이를 첫 번째 메시지로 보내서 인증할 수 있습니다:
{"seq": 1, "action": "authentication_challenge", "data": {"token": "…"}}
서버는 hello 이벤트를 보내고, 이후 볼 수 있는 모든 것에 대한 이벤트를 보내습니다:
{
"event": "posted",
"data": {"channel_id": "…", "channel_type": "O", "post": "{\"id\":\"…\",\"message\":\"Hello\",…}"},
"broadcast": {"channel_id": "…", "team_id": "", "user_id": "", "omit_users": null},
"seq": 4
}
data.post는 JSON 문자열인 게시글임을 유의하세요. 일반적인 이벤트: posted, post_edited, post_deleted, reaction_added, reaction_removed, typing, status_change, user_added, direct_added. 앱은 custom_<app id>_<event>로 명명된 자체 이벤트를 보내습니다.
증가하는 seq가 포함된 작업을 보낼 수도 있습니다: {"channel_id", "parent_id"}가 포함된 user_typing 또는 get_statuses. 연결이 끊기면 다시 연결하고, since로 놓친 것을 가져오세요( 페이지네이션 참고).
Antimatter는 다음 이벤트를 추가합니다: community_attributes_updated, member_timeouts_updated, post_put_on_top, post_removed_from_top, server_categories_updated, channel_overrides_updated 및 category_overrides_updated.
클라이언트 라이브러리
- 시작:
server/public/model의model.Client4(github.com/mattermost/mattermost/server/public/model가져오기).model.NewAPIv4Client(url)를 호출한 뒤client.SetToken(token)를 실행합니다.model.NewWebSocketClient4(wsURL, token)는 이벤트를 추적합니다. Antimatter의 코피는UpdateMessageRequest,PutPostOnTop,ExportChannel과 같은 자체 엔드포인트용 메서드를 추가합니다. - TypeScript:
webapp/platform/client의@mattermost/clientClient4클래스, 타입은webapp/platform/types에 있습니다. Antimatter 저장소의 복사본에는 Antimatter의 엔드포인트가 포함되어 있지만, Mattermost가 npm에 게시한 패키지에는 포함되어 있지 않습니다.
package main
import (
"context"
"log"
"github.com/mattermost/mattermost/server/public/model"
)
func main() {
client := model.NewAPIv4Client("https://chat.example.com")
client.SetToken("…")
post, _, err := client.CreatePost(context.Background(), &model.Post{
ChannelId: "…",
Message: "Hello from Go",
})
if err != nil {
log.Fatal(err)
}
log.Println("posted", post.Id)
}
Antimatter가 API에 추가한 내용
이 엔드포인트와 필드는 Mattermost 서버에 존재하지 않습니다. 모두 세션이 필요합니다.
| 엔드포인트 | 기능 |
|---|---|
GET /teams/{team_id}/user_attributes/fieldsPOST 동일한 경로PATCH, DELETE …/fields/{field_id} | 커뮤니티 속성: 커뮤니티 관리자가 멤버를 위해 정의하는 프로필 필드(최대 20개). 멤버는 읽을 수 있으며, 커뮤니티 관리자가 생성 및 변경합니다. |
GET /teams/{team_id}/members/{user_id}/user_attributesPATCH 동일한 경로POST /teams/{team_id}/user_attributes/values/search | {field_id: value} 형식의 멤버 속성 값. 멤버는 자신의 값을 설정할 수 있으며(관리자가 관리하는 필드 제외), 관리자는 누구의 값이든 설정할 수 있습니다. 검색은 {"user_ids": [...]}(최대 200개)를 받습니다. |
GET /teams/{team_id}/timeoutsPUT /teams/{team_id}/members/{user_id}/timeoutGET /teams/{team_id}/members/{user_id}/moderation | 타임아웃: {"until": time, "reason": "…"}는 해당 시점까지(최대 28일) 커뮤니티에서 게시, 반응, 업로드를 방지합니다. "until": 0은 이를 해제합니다. 모더레이션 뷰에서는 가입 시점과 최근 게시량을 보여줍니다. |
GET /channels/{channel_id}/on_topPUT, DELETE /posts/{post_id}/on_top | 채널 상단에 고정된 메시지(최대 10개). {"duration": ms}, 최대 30일; 0이면 삭제될 때까지 유지됩니다. 채널을 읽을 수 있는 사람은 목록을 볼 수 있습니다. 메시지를 상단에 고정하거나 해제하려면 채널에 게시할 권한이 필요하며, 커뮤니티의 채널인 경우 해당 채널 또는 커뮤니티의 관리자이거나 메시지 관리(delete_others_posts) 권한이 있어야 합니다. 다이렉트 메시지나 그룹 메시지의 경우 해당 멤버가 수행할 수 있습니다. 아카이브된 채널에서는 거부됩니다. |
POST /channels/{channel_id}/message_request | 자신의 메시지 요청에 대한 작업: {"action": "accept"}, "dismiss", 또는 요청 목록에 대화를 다시 넣기 위한 "request". 자신의 채널 멤버를 반환합니다. |
GET, PUT /channels/{channel_id}/overridesGET /channels/{channel_id}/overrides/effectiveGET, PUT /channels/{channel_id}/role_access | 채널에서 역할 또는 사용자가 수행할 수 있는 작업, 그리고 역할 기반 접근 제한이 설정된 채널을 볼 수 있는 역할입니다. |
GET, PUT /teams/{team_id}/server_categoriesGET, PUT …/server_categories/overrides | 커뮤니티의 공유 채널 카테고리, 그리고 해당 카테고리 내 모든 채널에 적용되는 예외 설정입니다. |
GET /groups/{group_id}/team_rolePUT …/team_role/permissions | 커뮤니티 역할이 부여하는 권한입니다. |
POST /teams/{team_id}/autolinks/preview | 커뮤니티의 자동 링크 규칙을 텍스트에 적용해 테스트합니다. |
POST /channels/{channel_id}/export?format=csv&since=&until= | 채널의 메시지를 CSV 파일로 다운로드합니다(최대 50,000개). 채널을 읽을 수 있는 사용자만 사용할 수 있습니다. |
GET /posts/{post_id}/speech | 텍스트 음성 변환(TTS)이 설정된 경우, 음성으로 낭독되는 메시지입니다. |
POST /posts/{post_id}/move_to_channel | 글타래를 같은 커뮤니티의 다른 채널로 이동합니다: 글타래 이동 참고. |
GET, POST /ai/connectionsGET, PATCH, DELETE /ai/connections/{connection_id}GET /ai/connections/usable | 모델 연결, 서버의 AI 기능과 앱이 사용하는 AI 제공자: 모델 연결 참고. |
GET /channels/{channel_id}/message_actionsPOST /posts/{post_id}/message_actions/{hook_id}GET, POST /hooks/outgoing/{hook_id}/icon | 메시지 작업: 사용자가 메시지 메뉴에서 실행하는 발신 웹훅. 메시지 작업 참고. |
새로운 필드
- 커뮤니티(
Team,PUT /teams/{team_id}/patch):all_channels_membership(모든 사람이 볼 수 있는 모든 채널에 참여),default_channel_id(새로운 멤버가 도착하는 곳; 비어 있으면 General),kind(community또는workplace: workplace에서는 채널 관리자가 자신의 채널도 아카이브할 수 있음; 새 커뮤니티는 서버의TeamSettings.DefaultCommunityKind를 사용하며 기본값은community),member_list_view(멤버 목록이 멤버를 그룹화하는 방식: 기본값인choice는 각 멤버가 선택할 수 있게 하며,roles또는teams는 방식을 고정),hide_role_colors,require_team_badges,onboarding및autolinks(둘 다 JSON 문자열). - 새 커뮤니티의 기본 채널은
town-square가 아닌general(일반)입니다. 0.9.0 업그레이드는 커뮤니티의town-square를general로 이름 변경하며, 기존 ID는 유지합니다. 단, 커뮤니티에 이미general채널이 있는 경우를 제외합니다. 기존 이름은 계속 작동합니다:GET /teams/{team_id}/channels/name/town-square,GET /teams/name/{team}/channels/name/town-square및 수신 웹훅의channel은 해당 이름의 채널이 없으면 커뮤니티의 기본 채널을 반환합니다. 새 코드에서는default_channel_id또는 이름general을 사용하세요. - 채널 링크:
#channel-name은 채널을 링크하며,~channel-name도 마찬가지입니다. 게시물의channel_mentions속성은 이렇게 링크된 채널을 나열합니다. 채널 이름이 아닌#word는 해시태그로 남습니다. Antimatter의 웹 인터페이스와 모바일 앱은#name을 작성합니다. - 보관된 채널에도 여전히 새 멤버를 추가할 수 있습니다(
POST /channels/{channel_id}/members)하며, 추가된 멤버는 과거 기록을 읽을 수 있습니다. 하지만 아무도 게시물을 작성하거나, 반응, 고정, 메시지 상단 배치, 채널 이름 변경, 멤버 역할 변경을 할 수 없습니다. - 인라인 답글:
"props": {"reply_to": "<post id>"}를 포함하는 게시물은 같은 채널의 해당 메시지를 인용합니다."reply_to_mention": false를 추가하면 작성자에게 알림을 보내지 않습니다. 서버는 인용된 메시지의 간략한 설명을metadata.reply_to에 채웁니다. - 스포일러:
"props": {"spoiler": true}를 사용하면 독자가 보기로 선택할 때까지 게시물의 텍스트와 파일이 숨겨집니다. - 무시 및 차단은 사용자 설정입니다. 범주는
user_block이며, 이름은 상대방의 ID를 따르고 값은ignore또는block입니다. 다이렉트 메시지가 요청으로 대기되는지 여부는 채널 멤버의notify_props.dm_request에 저장됩니다(pending,accepted또는dismissed). - 메시지 첨부 파일에는
stages와chart를 포함할 수 있습니다: 카드를 참조하세요.
글타래 이동
POST /posts/{post_id}/move_to_channel은 글타래, 그 첫 번째 메시지 및 모든 답글을 같은 커뮤니티의 다른 채널로 이동합니다. post_id는 첫 번째 메시지나 답글 중 어느 것이든 될 수 있습니다.
curl -X POST https://chat.example.com/api/v4/posts/$POST_ID/move_to_channel \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"channel_id": "'$TARGET_CHANNEL_ID'", "flatten": false}'
channel_id(필수): 글타래가 이동할 대상 채널.flatten(기본값false):true로 설정하면 답글이 글타래가 아닌 대상 채널의 일반 메시지가 됩니다. Fusion의 채널로 만들기 기능이 이를 사용합니다.
메시지는 작성자, 시간, 반응, 파일이 그대로 유지됩니다. 복사본에는 silent_notification 속성이 포함되어 있어 아무에게도 알림을 보내지 않습니다. 원본 메시지는 삭제됩니다. 응답은 새 ID가 부여된 이동된 첫 번째 메시지입니다.
글타래를 이동할 수 있는 사용자
- 글타래를 읽을 수 있고 대상 채널에 게시물을 작성할 수 있어야 합니다.
- 채널 관리자, 커뮤니티 관리자, 채널에서 메시지 관리(
delete_others_posts) 권한이 있는 사용자, 시스템 관리자는 모든 글타래를 이동할 수 있습니다. - 글타래 작성자는 두 채널이 모두 공개 채널이거나, 글타래의 모든 메시지가 작성자의 것일 때만 글타래를 이동할 수 있습니다. 그렇지 않으면
403응답과 함께api.post.move_thread.private_needs_moderator.app_errorID가 반환됩니다. - 두 채널은 같은 커뮤니티(다이렉트 메시지 또는 그룹 메시지 제외)에 있어야 하며, 서로 달라야 하고, 아카이브되지 않아야 합니다. 시스템 메시지와 읽은 후 삭제되는 메시지는 이동할 수 없습니다.
WranglerSettings.MoveThreadMaxCount메시지(기본값 100개, 0이면 제한 없음)보다 긴 글타래는 이동이 거부됩니다.
포인터와 메모
이동 시 system_wrangler 유형의 시스템 메시지가 두 개 생성됩니다. 기존 채널에는 포인터("13개의 메시지가 있는 글타래가 #target으로 이동했습니다")가, 대상 채널에는 메모("이 글타래는 #source에서 이동되었습니다")가 생성되며, 이동된 글타래 아래에, 또는 flatten 옵션을 사용할 경우 해당 메시지의 뒤에 배치됩니다. 메시지 텍스트 외에도, 프로퍼티를 통해 클라이언트가 채널 이름을 링크로 표시할 수 있습니다:
- 포인터:
MovedThreadPermalink,NumMessages,MovedThreadChannelId,MovedThreadTeamName,MovedThreadPostId그리고 공개 대상 채널의 경우MovedThreadChannelName및MovedThreadChannelDisplayName. - 메모:
MovedFromChannelId,MovedFromTeamName,MovedFromPostId(포인터),MovedFromPermalink그리고 공개 소스 채널의 경우MovedFromChannelName및MovedFromChannelDisplayName.
두 메시지 모두 TranslationID를 포함합니다. 비공개 채널의 이름은 포함되지 않으며, 읽는 사용자는 "다른 채널"을 확인합니다. Antimatter에서는 Mattermost의 자체 POST /posts/{post_id}/move가 비활성화되어 있으므로, 이 엔드포인트를 사용하세요.
모델 연결
모델 연결은 AI 제공자의 주소와 키를 의미하며, 관리자가 설정합니다. 서버의 AI 기능과 AI 서비스를 호출하는 앱들이 이를 사용합니다. 시스템 관리자는 서버 전체의 연결(manage_ai_connections)을 관리하고, 커뮤니티 관리자는 해당 커뮤니티의 연결(manage_team_ai_connections)을 관리합니다. 키는 쓰기 전용이며, 응답에는 키가 포함되지 않고 api_key_set와 api_key_last4만 반환됩니다.
| 엔드포인트 | 기능 |
|---|---|
GET /ai/connections?scope= | 관리하는 연결 목록. scope는 server 또는 커뮤니티 ID이며, 지정하지 않으면 관리 권한이 있는 모든 범위의 연결을 반환합니다. |
POST /ai/connections | 연결을 추가합니다(응답 201). |
POST /ai/connections/test, POST /ai/connections/models | 저장 전에 연결을 테스트하거나 해당 연결의 모델 목록을 조회합니다. 추가 요청과 동일한 바디를 사용하며, 아무것도 저장되지 않습니다. |
GET, PATCH(또는 PUT), DELETE /ai/connections/{connection_id} | 연결을 읽거나 변경하거나 삭제합니다. 패치는 변경할 필드만 포함하며, api_key를 생략하면 기존 키가 유지됩니다. |
POST /ai/connections/{connection_id}/test | 저장된 연결을 테스트합니다: {"ok", "error", "status_code", "latency_ms", "model_count"}. |
GET /ai/connections/{connection_id}/models | 제공자가 제공하는 모델 목록입니다. |
GET /ai/connections/{connection_id}/usage | 이번 달의 요청 및 토큰 사용량입니다. |
GET /ai/connections/usable?channel_id=&team_id= | 로그인한 모든 사용자를 위한 정보입니다. 해당 위치에서 사용할 수 있는 연결, 그 모델과 기능은 표시되지만, 키나 주소는 절대 표시되지 않습니다. |
새 연결의 본문:
{
"name": "Local models",
"scope": "server",
"provider": "openai_compatible",
"base_url": "http://llm.internal:8000/v1",
"api_key": "…",
"extra_headers": {},
"models": {"chat": "qwen3-32b", "embeddings": "", "transcription": "", "decisions": ""},
"limits": {"requests_per_minute": 0, "monthly_token_budget": 0, "per_user_requests_per_minute": 0, "per_user_monthly_token_budget": 0},
"sharing": {"all_teams": true, "team_ids": []},
"audience": {"everyone": true, "group_ids": [], "roles": [], "allow_guests": false}
}
provider는 openai_compatible 또는 anthropic입니다. scope의 기본값은 server이며, 커뮤니티 ID를 지정하면 해당 커뮤니티의 연결이 됩니다. limits에서 0은 제한이 없음을 의미하며, 분당 요청 수는 각 서버별로, 토큰 예산은 전체 클러스터 기준으로 달(UTC) 단위로 계산됩니다. sharing은 서버 전체 연결을 사용할 수 있는 커뮤니티를 지정하며(다이렉트 메시지와 그룹 메시지는 all_teams가 필요함), audience는 사용 권한이 있는 대상을 지정합니다. 게스트는 allow_guests가 설정된 경우에만 사용할 수 있습니다. 변경 사항은 감사 로그에 기록됩니다. 설정에 대한 자세한 내용은 AI 관리자 가이드를 참고하세요.