REST API
Усі дії, які виконують застосунки Antimatter, проходять через той самий HTTP API, тому ваші скрипти можуть робити те саме. На цій сторінці описано, як автентифікуватися, які ресурси ви використовуватимете найчастіше, як виглядають відповіді та помилки, а також як отримувати події в реальному часі через WebSocket.
Основи
- Базовий URL:
https://chat.example.com/api/v4. Усі наведені нижче адреси відносні до нього. - Формат: JSON на вході та на виході, окрім завантаження файлів (multipart). Надсилайте
Content-Type: application/json. - Ідентифікатори: кожен об’єкт має
idз 26 символів. Час вимірюється в мілісекундах від епохи Unix (create_at,update_at,delete_at; 0 означає «не видалено»). - Спільноти — це команди: API називає їх
teams, зteam_id. - Себе: будьде, де шлях приймає
user_id,meозначає користувача, який увійшов в систему, як уGET /users/me.
Повний список кінцевих точок міститься в коді сервера: маршрути оголошено в server/channels/api4/*.go, а типи — в server/public/model. Опис OpenAPI у папці api/v4/source репозиторію покриває кінцеві точки, успадковані від 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 для будь-яких дій, окрім GET; токен у заголовку Authorization не потребує CSRF-заголовка.Додатки OAuth 2.0
Щоб дозволити людям вхід до вашого застосунку за допомогою їхнього облікового запису Antimatter, зареєструйте додаток OAuth 2.0. Antimatter тоді виступає провайдером OAuth:
- Увімкнути постачальника послуг OAuth 2.0 має бути увімкнено (Системна консоль › Інтеграції › Управління інтеграцією,
ServiceSettings.EnableOAuthServiceProvider, за замовчуванням увімкнено). - Хтось із правом керування додатками OAuth (за замовчуванням — системні адміністратори) відкриває свій аватар, потім Інтеграції › Додатки OAuth 2.0 і додає додаток із його URL-адресами зворотного виклику. Вони отримують ідентифікатор клієнта та секрет клієнта.
- Ваша застосунка пересилає людей на
https://chat.example.com/oauth/authorizeзresponse_type=code,client_id,redirect_uriтаstate. Підтримується PKCE зcode_challenge_method=S256. - Вона обмінює код на
POST https://chat.example.com/oauth/access_token(grant_type=authorization_code, потімrefresh_tokenдля оновлення) і викликає API зAuthorization: Bearer <access token>.
Користувачі бачать додатки, які вони дозволили, в Профіль і налаштування › Безпека › Дозволені вами додатки.
Основні ресурси
| Що | Кінцеві точки |
|---|---|
| Ви та інші люди | 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 |
| Реакції | POST /reactions з {"user_id", "post_id", "emoji_name"}, DELETE /users/{user_id}/posts/{post_id}/reactions/{emoji_name} |
| Файли | POST /files (multipart: 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: user_typing із {"channel_id", "parent_id"} або 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.
Клієнтські бібліотеки
- Перейти:
model.Client4вserver/public/model(імпортgithub.com/mattermost/mattermost/server/public/model).model.NewAPIv4Client(url), потімclient.SetToken(token);model.NewWebSocketClient4(wsURL, token)стежить за подіями. Копія Antimatter додає методи для власних точок кінцевого доступу, наприкладUpdateMessageRequest,PutPostOnTopтаExportChannel. - TypeScript: клас
Client4з@mattermost/client, уwebapp/platform/client, з типами у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 | Повідомлення, озвучене як аудіо, коли налаштовано перетворення тексту в мовлення. |
POST /posts/{post_id}/move_to_channel | Переміщує обговорення в інший канал тієї ж спільноти: див. Переміщення обговорення. |
GET, POST /ai/connectionsGET, PATCH, DELETE /ai/connections/{connection_id}GET /ai/connections/usable | З’єднання з моделями, тобто провайдери ШІ, які використовуються функціями ШІ сервера та додатками: див. З’єднання з моделями. |
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). - Типовий канал нової спільноти —
general(Загальний), а неtown-square. Оновлення до 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 може бути 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 для цього використовується Make it a channel.
Повідомлення зберігають авторів, час, реакції та файли. Їхні копії містять властивість silent_notification, тому не надсилають сповіщень. Оригінальні повідомлення видаляються. У відповіді повертається перше повідомлення обговорення з його новим ID.
Хто може переміщати обговорення
- Ви повинні мати доступ до читання обговорення та до публікації в цільовому каналі.
- Адміністратори каналу, адміністратори спільноти, користувачі з правом Керування повідомленнями (
delete_others_posts) у каналі та системні адміністратори можуть переміщати будь-яке обговорення. - Автор обговорення може перемістити його, якщо обидва канали є відкритими, або якщо всі повідомлення в обговоренні належать йому. Інакше відповідь буде
403з IDapi.post.move_thread.private_needs_moderator.app_error. - Обидва канали мають належати до одного робочого середовища (приватні та групові повідомлення не підтримуються), бути різними та не архівованими. Системні повідомлення та повідомлення, що знищуються після прочитання, неможливо перемістити.
- Обговорення з кількістю повідомлень, що перевищує
WranglerSettings.MoveThreadMaxCount(за замовчуванням 100; 0 означає відсутність обмеження), відхиляється.
Показник та нотатка
Після переміщення залишаються два системні повідомлення типу system_wrangler: показник у старому каналі («Обговорення з 13 повідомленнями переміщено до #target») та нотатка в цільовому каналі («Це обговорення переміщено з #source»), під переміщеним обговоренням або, за використання flatten, після його повідомлень. Окрім тексту повідомлення, їхні властивості дозволяють клієнту відображати назву каналу як посилання:
- Показник:
MovedThreadPermalink,NumMessages,MovedThreadChannelId,MovedThreadTeamName,MovedThreadPostIdта, для відкритого цільового каналу,MovedThreadChannelNameіMovedThreadChannelDisplayName. - Нотатка:
MovedFromChannelId,MovedFromTeamName,MovedFromPostId(показник),MovedFromPermalinkта, для відкритого початкового каналу,MovedFromChannelNameіMovedFromChannelDisplayName.
Обидва також містять TranslationID. Назву приватного каналу не вказано: читачі бачать «інший канал». Власний POST /posts/{post_id}/move у Mattermost вимкнено в Antimatter; використовуйте цей endpoint.
Підключення моделей
Модельне з’єднання — це адреса та ключ постачальника ШІ, які налаштовує адміністратор. Серверні функції ШІ та додатки, що викликають службу ШІ, використовують ці з’єднання. Системні адміністратори керують серверними з’єднаннями (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; ідентифікатор спільноти робить його з’єднанням цієї спільноти. У limits значення 0 означає відсутність обмежень; запити на хвилину рахуються на кожному сервері, а бюджети токенів — на календарний місяць (UTC) для всієї кластерної системи. sharing визначає, які спільноти можуть використовувати серверне з’єднання (для приватних та групових повідомлень потрібен all_teams), а audience — хто може ним користуватися; гості — лише за наявності allow_guests. Зміни записуються в журнал аудиту. Налаштування описано в адміністративному посібнику: див. ШІ.