REST API
Semua yang dilakukan oleh aplikasi Antimatter melewati HTTP API yang sama, sehingga skrip Anda juga dapat melakukannya. Halaman ini menjelaskan cara melakukan autentikasi, sumber daya yang paling sering Anda gunakan, bagaimana bentuk respons dan kesalahan, serta cara mengikuti peristiwa secara langsung melalui WebSocket.
Dasar-dasar
- URL Dasar:
https://chat.example.com/api/v4. Semua endpoint di bawah ini relatif terhadap URL tersebut. - Format: JSON masuk dan keluar, kecuali unggahan file (multipart). Kirim
Content-Type: application/json. - ID: setiap objek memiliki
id26 karakter. Waktu adalah milidetik sejak epoch Unix (create_at,update_at,delete_at; 0 berarti "tidak dihapus"). - Komunitas adalah tim: API menyebutnya
teams, denganteam_id. - Diri Anda: di mana pun jalur menerima
user_id,meberarti pengguna yang sedang masuk, seperti dalamGET /users/me.
Daftar lengkap endpoint ada di kode server: rute dideklarasikan di server/channels/api4/*.go dan tipe di server/public/model. Deskripsi OpenAPI di folder api/v4/source repositori mencakup endpoint yang diwarisi dari Mattermost, serta beberapa tambahan Antimatter: memindahkan utas, koneksi model, dan aksi pesan. Sisanya hanya ada di kode.
Autentikasi
Setiap permintaan, kecuali masuk dan beberapa endpoint publik, membutuhkan token di header Authorization:
curl -H "Authorization: Bearer $TOKEN" https://chat.example.com/api/v4/users/me
Tiga jenis token diterima di sana: token akses pribadi, token sesi, dan token akses OAuth. Authorization: Token … juga diterima. Token di string kueri (?access_token=) hanya diterima untuk token akses OAuth.
Token akses pribadi (disarankan untuk skrip)
Token akses pribadi bertindak sebagai Anda, tidak kedaluwarsa kecuali Anda memberikannya tanggal kedaluwarsa, dan dapat dicabut kapan saja. Token akses pribadi nonaktif secara bawaan:
- Admin sistem mengaktifkan Aktifkan Token Akses Pribadi di Konsol Sistem › Integrasi › Manajemen Integrasi (
ServiceSettings.EnableUserAccessTokens,AM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS). - Untuk setiap orang yang dapat membuat token, admin sistem membuka Konsol Sistem › Manajemen Pengguna › Pengguna, memilih Kelola peran di menu orang tersebut, dan mencentang Izinkan akun ini untuk membuat token akses pribadi. Admin sistem selalu dapat membuat token.
- Orang tersebut membuka avatar mereka di kanan atas, lalu Profil & pengaturan › Keamanan. Di bawah Token akses pribadi, mereka menjelaskan kegunaan token dan memilih Buat token. Token hanya ditampilkan sekali: salin.
Dengan API: POST /users/{user_id}/tokens dengan {"description": "backup script", "expires_at": 0} (expires_at dalam milidetik; 0 untuk tidak ada). Field token dalam respons adalah rahasia; id adalah yang Anda gunakan untuk mencabutnya (POST /users/tokens/revoke dengan {"token_id": "…"}). Dari baris perintah: amctl token generate <user> <description>.
Admin sistem dapat membatasi masa berlaku token dengan Masa Berlaku Maksimum Token Akses Pribadi (hari) di halaman Konsol Sistem yang sama.
Token sesi
Masuk dengan kata sandi mengembalikan token sesi di header respons Token, jenis sesi yang sama yang digunakan aplikasi:
curl -i -X POST https://chat.example.com/api/v4/users/login \
-H 'Content-Type: application/json' \
-d '{"login_id": "maya", "password": "…"}'
Tambahkan "token": "123456" untuk akun dengan autentikasi multi-faktor. Sesi kedaluwarsa sesuai pengaturan sesi server, dan endpoint login dibatasi laju (5 permintaan per detik). POST /users/logout mengakhiri sesi.
X-CSRF-Token untuk apa pun selain GET; token di header Authorization tidak memerlukan header CSRF.Aplikasi OAuth 2.0
Untuk memungkinkan orang masuk ke aplikasi Anda dengan akun Antimatter mereka, daftarkan aplikasi OAuth 2.0. Antimatter kemudian menjadi penyedia OAuth:
- Aktifkan Penyedia Layanan OAuth 2.0 harus diaktifkan (Konsol Sistem › Integrasi › Manajemen Integrasi,
ServiceSettings.EnableOAuthServiceProvider, diaktifkan secara default). - Seseorang yang memiliki hak untuk mengelola aplikasi OAuth (admin sistem secara default) membuka avatar mereka, lalu Integrasi › Aplikasi OAuth 2.0, dan menambahkan aplikasi dengan URL callback. Mereka mendapatkan ID klien dan rahasia klien.
- Aplikasi Anda mengarahkan pengguna ke
https://chat.example.com/oauth/authorizedenganresponse_type=code,client_id,redirect_uri, danstate. PKCE dengancode_challenge_method=S256didukung. - Kode ditukarkan di
POST https://chat.example.com/oauth/access_token(grant_type=authorization_code, lalurefresh_tokenuntuk memperbarui), dan API dipanggil denganAuthorization: Bearer <access token>.
Pengguna dapat melihat aplikasi yang mereka izinkan di Profil & Pengaturan › Keamanan › Aplikasi yang Anda izinkan.
Sumber daya utama
| Apa | Endpoint |
|---|---|
| Anda dan pengguna lain | GET /users/me, GET /users/{user_id}, GET /users/username/{username}, POST /users/ids (daftar ID), POST /users/search, GET /users?in_team=…&in_channel=… |
| Komunitas | 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 |
| Kanal | GET /users/me/teams/{team_id}/channels, GET /teams/name/{team}/channels/name/{channel}, POST /channels, POST /channels/direct (dua ID pengguna), POST /channels/group, POST /channels/{channel_id}/members |
| Pesan (posts) | 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 |
| Reaksi | POST /reactions dengan {"user_id", "post_id", "emoji_name"}, DELETE /users/{user_id}/posts/{post_id}/reactions/{emoji_name} |
| Berkas | POST /files (multipart: channel_id dan files), lalu masukkan ID yang dikembalikan ke file_ids pada pesan; GET /files/{file_id} |
| Preferensi | GET /users/me/preferences, PUT /users/me/preferences |
| Integrasi | /hooks/incoming, /hooks/outgoing, /commands, /bots, /oauth/apps (lihat halaman berikutnya) |
| Server | GET /system/ping (kesehatan, tidak memerlukan token), GET /config/client?format=old (pengaturan yang dilihat klien) |
Kirim pesan
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"}'
Pesan menggunakan Markdown. Tambahkan "root_id" (pesan pertama dari utas) untuk membalas dalam utas, "file_ids" untuk berkas, dan "props" untuk lampiran dan tambahan lainnya (lihat Lampiran).
Cari ID kanal
curl -H "Authorization: Bearer $TOKEN" \
https://chat.example.com/api/v4/teams/name/lumen-labs/channels/name/ops-alerts
Nama-nama tersebut adalah nama yang ada di tautan kanal: /lumen-labs/channels/ops-alerts.
Paginasi
Endpoint daftar menerima page (mulai dari 0) dan per_page (60 secara default, maksimal 200). Terus minta halaman berikutnya sampai halaman yang dikembalikan lebih pendek dari per_page.
Pesan pada sebuah kanal (GET /channels/{channel_id}/posts) juga menerima parameter since (waktu: semua perubahan sejak saat itu), atau before dan after (ID pesan). Hasilnya berupa daftar pesan: {"order": [IDs, newest first], "posts": {ID: post}, "next_post_id", "prev_post_id"}.
Kesalahan
Kesalahan menggunakan kode status HTTP yang umum (400 masukan salah, 401 belum masuk, 403 tidak diizinkan, 404 tidak ditemukan, 501 fitur dimatikan) dan isi JSON:
{
"id": "api.context.permissions.app_error",
"message": "You do not have the appropriate permissions.",
"detailed_error": "",
"request_id": "jz8zm5nunpbt8f3gpqsz5dq6so",
"status_code": 403
}
Gunakan id di kode Anda: message diterjemahkan ke bahasa pengguna. detailed_error kosong kecuali server berjalan dalam mode pengembang (ServiceSettings.EnableDeveloper). Sampaikan request_id ke admin server: ID ini ada di log.
Batas Laju
Batas laju dimatikan secara bawaan. Ketika admin sistem mengaktifkannya (Konsol Sistem › Lingkungan › Batas Laju), setiap klien mendapat 10 permintaan per detik dengan lonjakan hingga 100 secara bawaan, dihitung berdasarkan alamat IP atau pengguna. Respons membawa X-RateLimit-Limit, X-RateLimit-Remaining, dan X-RateLimit-Reset; jika melebihi batas, server menjawab 429 dengan header Retry-After dalam detik. Beberapa titik akhir, seperti masuk, memiliki batasnya sendiri terlepas dari pengaturan.
Tulis skrip yang menunggu dan mencoba lagi saat 429, dan hindari polling: ikuti WebSocket saja.
Aliran peristiwa WebSocket
Hubungkan ke wss://chat.example.com/api/v4/websocket. Autentikasi dengan header Authorization: Bearer pada permintaan koneksi, atau dengan mengirim ini sebagai pesan pertama:
{"seq": 1, "action": "authentication_challenge", "data": {"token": "…"}}
Server mengirim peristiwa hello, lalu peristiwa untuk semua yang Anda diizinkan untuk melihat:
{
"event": "posted",
"data": {"channel_id": "…", "channel_type": "O", "post": "{\"id\":\"…\",\"message\":\"Hello\",…}"},
"broadcast": {"channel_id": "…", "team_id": "", "user_id": "", "omit_users": null},
"seq": 4
}
Perhatikan bahwa data.post adalah pesan sebagai string JSON. Peristiwa umum: posted, post_edited, post_deleted, reaction_added, reaction_removed, typing, status_change, user_added, direct_added. Aplikasi mengirim peristiwanya sendiri, bernama custom_<app id>_<event>.
Anda juga dapat mengirim aksi, masing-masing dengan seq yang meningkat: user_typing dengan {"channel_id", "parent_id"}, atau get_statuses. Hubungkan ulang saat koneksi terputus, dan ambil yang terlewat dengan since (lihat Paginasi).
Antimatter menambahkan event-event berikut: community_attributes_updated, member_timeouts_updated, post_put_on_top, post_removed_from_top, server_categories_updated, channel_overrides_updated, dan category_overrides_updated.
Perpustakaan klien
- Lanjut:
model.Client4diserver/public/model(imporgithub.com/mattermost/mattermost/server/public/model).model.NewAPIv4Client(url), laluclient.SetToken(token);model.NewWebSocketClient4(wsURL, token)mengikuti peristiwa. Salinan Antimatter menambahkan metode untuk endpoint miliknya sendiri, sepertiUpdateMessageRequest,PutPostOnTop, danExportChannel. - TypeScript: kelas
Client4dari@mattermost/client, diwebapp/platform/client, dengan tipenya diwebapp/platform/types. Salinan di repositori Antimatter mencakup endpoint Antimatter; paket yang dipublikasikan di npm oleh Mattermost tidak.
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)
}
Yang ditambahkan Antimatter ke API
Endpoint dan field ini tidak ada di server Mattermost. Semuanya membutuhkan sesi.
| Endpoint | Fungsinya |
|---|---|
GET /teams/{team_id}/user_attributes/fieldsPOST jalur yang samaPATCH, DELETE …/fields/{field_id} | Atribut komunitas: field profil yang didefinisikan oleh admin komunitas untuk anggotanya (maksimum 20). Anggota dapat membacanya; admin komunitas membuatnya dan mengubahnya. |
GET /teams/{team_id}/members/{user_id}/user_attributesPATCH jalur yang samaPOST /teams/{team_id}/user_attributes/values/search | Nilai atribut anggota, sebagai {field_id: value}. Anggota mengatur milik mereka sendiri (kecuali yang dikelola admin); admin mengatur milik siapa pun. Pencarian menerima {"user_ids": [...]} (maksimum 200). |
GET /teams/{team_id}/timeoutsPUT /teams/{team_id}/members/{user_id}/timeoutGET /teams/{team_id}/members/{user_id}/moderation | Jeda: {"until": time, "reason": "…"} mencegah seseorang memposting, bereaksi, dan mengunggah di komunitas hingga waktu tersebut (maksimum 28 hari); "until": 0 mencabutnya. Tampilan moderasi menunjukkan kapan mereka bergabung dan seberapa banyak mereka memposting belakangan ini. |
GET /channels/{channel_id}/on_topPUT, DELETE /posts/{post_id}/on_top | Pesan yang dipin di bagian atas kanal (maksimal 10). {"duration": ms}, maksimal 30 hari; 0 berarti dipertahankan sampai dihapus. Siapa pun yang dapat membaca kanal dapat melihat daftar ini. Memin atau melepas pin pesan membutuhkan hak untuk mengirim pesan di kanal tersebut dan, di kanal komunitas, menjadi admin kanal atau komunitas, atau memiliki Kelola pesan (delete_others_posts) di sana. Untuk pesan langsung atau grup, anggotanya yang dapat melakukannya. Ditolak di kanal yang diarsipkan. |
POST /channels/{channel_id}/message_request | Bertindak pada permintaan pesan Anda sendiri: {"action": "accept"}, "dismiss", atau "request" untuk mengembalikan percakapan ke antara permintaan. Mengembalikan anggota kanal Anda. |
GET, PUT /channels/{channel_id}/overridesGET /channels/{channel_id}/overrides/effectiveGET, PUT /channels/{channel_id}/role_access | Apa yang dapat dilakukan oleh peran atau seseorang di sebuah kanal, dan peran mana yang dapat melihat kanal yang dikunci oleh peran. |
GET, PUT /teams/{team_id}/server_categoriesGET, PUT …/server_categories/overrides | Kategori kanal bersama komunitas, dan pengecualian yang berlaku untuk setiap kanal dalam sebuah kategori. |
GET /groups/{group_id}/team_rolePUT …/team_role/permissions | Izin yang diberikan oleh peran komunitas. |
POST /teams/{team_id}/autolinks/preview | Menguji aturan autolink komunitas pada sebuah teks. |
POST /channels/{channel_id}/export?format=csv&since=&until= | Mengunduh pesan sebuah kanal sebagai CSV (hingga 50.000), untuk orang-orang yang dapat membaca kanal tersebut. |
GET /posts/{post_id}/speech | Pesan yang dibacakan, sebagai audio, ketika teks-ke-suara disetel. |
POST /posts/{post_id}/move_to_channel | Memindahkan utas ke kanal lain dalam komunitas yang sama: lihat Memindahkan utas. |
GET, POST /ai/connectionsGET, PATCH, DELETE /ai/connections/{connection_id}GET /ai/connections/usable | Koneksi model, penyedia AI yang digunakan oleh fitur AI dan aplikasi server: lihat Koneksi model. |
GET /channels/{channel_id}/message_actionsPOST /posts/{post_id}/message_actions/{hook_id}GET, POST /hooks/outgoing/{hook_id}/icon | Aksi pesan: webhook keluar yang dijalankan orang dari menu pesan. Lihat Aksi pesan. |
Bidang baru
- Komunitas (
Team, danPUT /teams/{team_id}/patch):all_channels_membership(semua orang ada di setiap kanal yang dapat mereka lihat),default_channel_id(tempat pendaratan orang baru; kosong berarti General),kind(communityatauworkplace: di workplace, admin kanal juga dapat mengarsipkan kanal mereka; komunitas baru mendapatkanTeamSettings.DefaultCommunityKindserver,communitysecara default),member_list_view(cara daftar anggota mengelompokkan anggota:choice, default, memungkinkan setiap anggota memilih;rolesatauteamsmengaturnya tetap),hide_role_colors,require_team_badges,onboardingdanautolinks(keduanya string JSON). - Kanal default komunitas baru adalah
general(Umum), bukantown-square. Pembaruan 0.9.0 mengganti namatown-squaresetiap komunitas menjadigeneral, dengan ID yang tetap, kecuali komunitas tersebut sudah memiliki kanalgeneral. Nama lama tetap berfungsi:GET /teams/{team_id}/channels/name/town-square,GET /teams/name/{team}/channels/name/town-square, danchanneldari webhook masuk akan mengarah ke kanal default komunitas jika tidak ada kanal dengan nama tersebut. Gunakandefault_channel_id, atau namageneral, di kode baru. - Tautan kanal:
#channel-namemenautkan sebuah kanal, sama seperti~channel-name. Propertichannel_mentionspada kiriman mencantumkan kanal-kanal yang ditautkan dengan cara mana pun;#wordyang tidak menyebut nama kanal tetap menjadi tagar. Antarmuka web dan aplikasi seluler Antimatter menulis#name. - Kanal yang diarsipkan masih dapat menerima anggota baru (
POST /channels/{channel_id}/members), yang dapat membaca riwayatnya. Tidak ada yang dapat mengirim pesan, bereaksi, menyematkan, memindahkan pesan ke atas, mengganti nama kanal, atau mengubah peran anggota di sana. - Balasan inline: sebuah kiriman dengan
"props": {"reply_to": "<post id>"}mengutip pesan tersebut dari kanal yang sama. Tambahkan"reply_to_mention": falseuntuk tidak memberi tahu penulisnya. Server mengisimetadata.reply_todengan deskripsi singkat dari pesan yang dikutip. - Spoiler:
"props": {"spoiler": true}menyembunyikan teks dan file sebuah kiriman sampai pembaca memilih untuk melihatnya. - Abai dan blokir adalah preferensi: kategori
user_block, dinamai sesuai ID orang lain, dengan nilaiignoreataublock. Apakah pesan langsung menunggu sebagai permintaan ada dinotify_props.dm_requestanggota kanal Anda (pending,acceptedataudismissed). - Lampiran pesan dapat membawa
stagesdanchart: lihat Kartu.
Pindahkan utas
POST /posts/{post_id}/move_to_channel memindahkan utas, pesan pertamanya, dan semua balasannya, ke kanal lain dalam komunitas yang sama. post_id dapat berupa pesan pertama atau balasan mana pun.
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(wajib): kanal tujuan untuk memindahkan utas.flatten(defaultfalse):truemenjadikan balasan sebagai pesan di kanal tujuan, bukan sebagai utas. Jadikan sebagai kanal di Fusion menggunakan ini.
Pesan-pesan tersebut mempertahankan penulis, waktu, reaksi, dan file. Salinannya memiliki properti silent_notification, sehingga tidak memberi notifikasi kepada siapa pun. Pesan asli dihapus. Respons adalah pesan pertama yang dipindahkan, dengan ID barunya.
Siapa yang dapat memindahkan utas
- Anda harus dapat membaca utas dan mengirim pesan di kanal tujuan.
- Admin kanal, admin komunitas, orang-orang dengan Kelola pesan (
delete_others_posts) di kanal, dan admin sistem dapat memindahkan utas mana pun. - Penulis utas dapat memindahkannya jika kedua kanal bersifat publik, atau jika semua pesan dalam utas adalah miliknya. Jika tidak, responsnya adalah
403dengan IDapi.post.move_thread.private_needs_moderator.app_error. - Kedua kanal harus berada di komunitas yang sama (bukan pesan langsung atau grup), berbeda, dan tidak diarsipkan. Pesan sistem dan pesan yang dibakar setelah dibaca tidak dapat dipindahkan.
- Utas dengan lebih dari
WranglerSettings.MoveThreadMaxCountpesan (100 secara bawaan; 0 untuk tanpa batas) akan ditolak.
Penunjuk dan catatan
Pemindahan ini meninggalkan dua pesan sistem bertipe system_wrangler: penunjuk di kanal lama ("Utas dengan 13 pesan telah dipindahkan ke #target") dan catatan di tujuan ("Utas ini dipindahkan dari #source"), di bawah utas yang dipindahkan atau, dengan flatten, setelah pesan-pesannya. Selain teks pesan, properti mereka memungkinkan klien menggambar nama kanal sebagai tautan:
- Penunjuk:
MovedThreadPermalink,NumMessages,MovedThreadChannelId,MovedThreadTeamName,MovedThreadPostId, dan, untuk tujuan publik,MovedThreadChannelNamedanMovedThreadChannelDisplayName. - Catatan:
MovedFromChannelId,MovedFromTeamName,MovedFromPostId(penunjuk),MovedFromPermalink, dan, untuk sumber publik,MovedFromChannelNamedanMovedFromChannelDisplayName.
Keduanya juga memiliki TranslationID. Nama kanal privat tidak ditampilkan: pembaca melihat "kanal lain". Endpoint POST /posts/{post_id}/move milik Mattermost sendiri tetap nonaktif di Antimatter; gunakan endpoint ini.
Koneksi model
Koneksi model adalah alamat dan kunci penyedia AI, yang diatur oleh admin. Fitur AI server dan aplikasi yang memanggil layanan AI menggunakannya. Admin sistem mengelola koneksi tingkat server (manage_ai_connections); admin komunitas mengelola koneksi komunitas mereka sendiri (manage_team_ai_connections). Kunci bersifat hanya-tulis: tidak ada respons yang memuat kunci, hanya api_key_set dan api_key_last4.
| Endpoint | Fungsinya |
|---|---|
GET /ai/connections?scope= | Koneksi yang Anda kelola. scope adalah server atau ID komunitas; tanpa itu, semua cakupan yang Anda kelola. |
POST /ai/connections | Menambahkan koneksi (menjawab 201). |
POST /ai/connections/test, POST /ai/connections/models | Menguji koneksi, atau mendaftar modelnya, sebelum disimpan. Badan permintaan sama seperti saat menambahkan; tidak ada yang disimpan. |
GET, PATCH (atau PUT), DELETE /ai/connections/{connection_id} | Membaca, mengubah, atau menghapus koneksi. Patch hanya membawa field yang akan diubah; tinggalkan api_key kosong untuk mempertahankan kunci. |
POST /ai/connections/{connection_id}/test | Menguji koneksi yang tersimpan: {"ok", "error", "status_code", "latency_ms", "model_count"}. |
GET /ai/connections/{connection_id}/models | Model-model yang ditawarkan oleh penyedia. |
GET /ai/connections/{connection_id}/usage | Permintaan dan token bulan ini. |
GET /ai/connections/usable?channel_id=&team_id= | Untuk semua orang yang masuk: koneksi yang dapat Anda gunakan di sana, beserta model dan kemampuannya, tanpa pernah menampilkan kunci atau alamatnya. |
Isi badan koneksi baru:
{
"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 adalah openai_compatible atau anthropic. scope secara bawaan adalah server; ID komunitas membuatnya menjadi koneksi komunitas tersebut. Di limits, 0 berarti tanpa batas; permintaan per menit dihitung di setiap server, sedangkan anggaran token per bulan kalender (UTC) untuk seluruh kluster. sharing menentukan komunitas mana yang dapat menggunakan koneksi tingkat server (pesan langsung dan grup membutuhkan all_teams), dan audience menentukan siapa yang dapat menggunakannya; tamu hanya jika allow_guests diaktifkan. Perubahan dicatat ke log audit. Panduan admin menjelaskan pengaturan ini: lihat AI.