Проект предоставляет простой JSON API по пути /api/v1/.
API поддерживает регистрацию, авторизацию, создание комнат, синхронизацию событий, управление участниками и отправку сообщений.
Все запросы, которые изменяют или читают пользовательские данные, требуют заголовок Authorization с bearer-токеном.
Content-Type: application/jsonAuthorization: Bearer <token>
Токен возвращается при вызове
/api/v1/authorization/и обязателен для защищённых запросов.
- URL:
/api/v1/registration/ - Метод:
POST - Тело:
login(string) — логин пользователяpassword(string) — пароль пользователя
Пример тела запроса:
{
"login": "alice",
"password": "secret123"
}Успешный ответ:
{
"status": "ok"
}Пример ошибки:
{
"error": "A user with this name already exists."
}- URL:
/api/v1/authorization/ - Метод:
POST - Тело:
login(string)password(string)
Пример тела запроса:
{
"login": "alice",
"password": "secret123"
}Успешный ответ:
{
"status": "ok",
"user_id": "@alice:example.com",
"token": "<jwt-token>"
}Примеры ошибок:
{
"error": "Incorrect login or password"
}{
"error": "Unable to obtain a token"
}Для всех защищённых запросов требуется заголовок Authorization:
Authorization: Bearer <token>Токен действует примерно один час.
- URL:
/api/v1/createRoom/ - Метод:
POST - Тело:
name(string) — название комнаты
Пример тела запроса:
{
"name": "Моя комната"
}Успешный ответ:
{
"status": "ok"
}Ошибка:
{
"error": "Something was wrong"
}- URL:
/api/v1/joined_rooms/ - Метод:
GETилиPOST - Требуется авторизация
Эндпойнт возвращает список комнат, в которых у пользователя статус участника join или invite.
Пример ответа:
[
{
"room_id": "!uuid:example.com",
"name": "Моя комната",
"creator": "@alice:example.com",
"topic": null,
"cdate": 1690000000
}
]- URL:
/api/v1/sync/ - Метод:
GET - Требуется авторизация
- Параметры запроса:
since(integer, необязательно) — метка времени в секундах, возвращаются события после этого времени
Пример запроса:
GET /api/v1/sync/?since=1690000000Пример ответа:
{
"next_batch": 1690000001,
"rooms": {
"invite": {
"!roomid:example.com": {
"invite_state": {
"events": []
}
}
},
"join": {
"!roomid:example.com": {
"events": [
{
"event_id": "$uuid",
"json": {
"event_id": "$uuid",
"type": "m.text",
"room_id": "!roomid:example.com",
"sender": "@alice:example.com",
"origin_server_ts": 1690000000000,
"content": {
"body": "Hello",
"room_id": "!roomid:example.com",
"sender": "@alice:example.com"
}
}
}
]
}
}
}
}Эндпойнты находятся по пути /api/v1/rooms/ и требуют авторизации и корректный идентификатор комнаты.
- URL:
/api/v1/rooms/ - Метод:
POST - Тело:
room_id(string) — идентификатор комнатыmsgtype(string) — тип события, для сообщения используйтеm.textbody(string) — текст сообщения
Пример тела запроса:
{
"room_id": "!roomid:example.com",
"msgtype": "m.text",
"body": "Привет мир"
}Успешный ответ:
{
"status": "ok",
"event_id": "$uuid"
}Ошибки:
{
"error": "Room not found"
}{
"error": "Sending a message is prohibited"
}- URL:
/api/v1/rooms/{roomId}/members/ - Метод:
GETилиPOST - Требуется авторизация
Возвращает записи членства для указанной комнаты.
Пример ответа:
[
{
"event_id": "$uuid",
"user_id": "@alice:example.com",
"sender": "@alice:example.com",
"room_id": "!roomid:example.com",
"membership": "join"
}
]- URL:
/api/v1/rooms/{roomId}/invite/ - Метод:
POST - Требуется авторизация
- Тело:
user_id(string) — полный идентификатор пользователя, например@bob:example.com
Пример тела запроса:
{
"user_id": "@bob:example.com"
}Успешный ответ:
{
"status": "ok"
}Если пользователь не найден, ответ будет:
{
"error": "Unable to find user"
}- URL:
/api/v1/rooms/{roomId}/accept/ - Метод:
POST - Требуется авторизация
Этот эндпойнт обновляет статус участника на join.
Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/rooms/{roomId}/ban/ - Метод:
POST - Требуется авторизация
- Тело:
user_id(string) — полный идентификатор пользователя для бана
Пример тела запроса:
{
"user_id": "@bob:example.com"
}Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/rooms/{roomId}/unban/ - Метод:
POST - Требуется авторизация
- Тело:
user_id(string)
Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/rooms/{roomId}/update/ - Метод:
POST - Требуется авторизация
- Доступно только создателю комнаты
Тело (все поля опциональны):
name(string) — новое названиеtopic(string) — новая темаjoin_rule(string) —publicилиinvite
Пример тела запроса:
{
"name": "Новое название",
"topic": "Обсуждение проекта",
"join_rule": "public"
}Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/rooms/{roomId}/upload_avatar/ - Метод:
POST - Требуется авторизация
- Доступно только создателю комнаты
- Формат:
multipart/form-data
Поля:
file(file) — изображение. Допустимые расширения: jpg, jpeg, png, gif, webp
Успешный ответ:
{
"status": "ok",
"file_url": "/f/1680000000_abcdef123456_avatar.png"
}- URL:
/api/v1/rooms/{roomId}/delete/ - Метод:
POST - Требуется авторизация
- Удалить может автор сообщения или создатель комнаты
Тело:
event_id(string) — идентификатор события
Пример тела запроса:
{
"event_id": "$uuid"
}Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/profile/ - Метод:
GETилиPOST - Требуется авторизация
Возвращает данные профиля текущего пользователя:
{
"user_id": "@alice:example.com",
"name": "alice",
"avatar_url": "/f/avatar.png",
"email": ""
}Обновление профиля. Формат: application/json или multipart/form-data.
Поля:
avatar_url(string) — URL аватараavatar(file) — файл изображения (jpg, jpeg, png, gif, webp). Если передан,avatar_urlигнорируетсяnew_password(string) — новый парольold_password(string) — текущий пароль (обязателен при смене пароля)
Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/logout/ - Метод:
POST - Требуется авторизация
Удаляет текущий токен доступа.
Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/public_rooms/ - Метод:
GET - Требуется авторизация
Параметры запроса:
q(string, опционально) — поисковый запрос для фильтрации по названию
Пример запроса:
GET /api/v1/public_rooms/?q=chatУспешный ответ:
[
{
"room_id": "!uuid:example.com",
"name": "My Room",
"topic": "Room topic",
"join_rule": "public",
"member_count": 5
}
]- URL:
/api/v1/join_room/ - Метод:
POST - Требуется авторизация
Тело:
room_id(string) — идентификатор комнаты
Пример тела запроса:
{
"room_id": "!uuid:example.com"
}Успешный ответ:
{
"status": "ok"
}Файлы отправляются на тот же эндпойнт, что и текстовые сообщения: POST /api/v1/rooms/.
Формат: multipart/form-data.
Поля:
room_id(string) — идентификатор комнатыmsgtype(string) —m.filefile(file) — загружаемый файлbody(string, опционально) — подпись к файлуreply_to(string, опционально) — event_id сообщения, на которое отвечаете
Вместо одного файла отправляется несколько запросов — по одному на каждый чанк.
Поля каждого запроса:
room_id(string) — идентификатор комнатыmsgtype(string) —m.fileupload_id(string) — уникальный идентификатор загрузки (напр.1670000000_random)chunk_index(int) — номер чанка (1-based)chunk_count(int) — общее количество чанковfile_name(string) — оригинальное имя файлаfile_size(int) — полный размер файлаfile(file) — бинарные данные чанкаbody(string, опционально) — добавляется только в последний чанк
Ответ на промежуточные чанки:
{
"status": "chunk_received",
"chunk_index": 1,
"chunk_count": 3
}Ответ на последний чанк (успешная загрузка):
{
"status": "ok",
"event_id": "$uuid"
}- URL:
/api/v1/version/ - Метод:
GET - Авторизация не требуется
Возвращает MD5-хеш файла rooms.js для автообновления страницы при изменении кода.
Успешный ответ:
{
"hash": "d41d8cd98f00b204e9800998ecf8427e"
}- Все данные запроса должны быть в JSON формате.
- API использует JWT-токены, хранящиеся в таблице
access_tokens. - Неверный или отсутствующий токен возвращает HTTP
401и JSON с ошибкой. - Формат
user_id:@login:domain, где домен задаётся черезWCO::$domain. - Идентификаторы комнат создаются в формате
!<uuid>:domain.
- URL:
/api/v1/presence/ - Метод:
POST - Требуется авторизация
Heartbeat присутствия. Отправьте запрос каждые 10-15 секунд для поддержания онлайн-статуса. Возвращает список ID онлайн-пользователей.
Успешный ответ:
{
"online": ["@alice:example.com", "@bob:example.com"]
}- URL:
/api/v1/typing/ - Метод:
POST - Требуется авторизация
- Тело:
room_id(string) — идентификатор комнаты
Успешный ответ:
{
"status": "ok",
"typing": ["@bob:example.com"]
}- URL:
/api/v1/typing/ - Метод:
DELETE - Требуется авторизация
- Тело:
room_id(string)
- URL:
/api/v1/getTyping/?room_id=!roomid:example.com - Метод:
GET - Требуется авторизация
Успешный ответ:
{
"typing": ["@bob:example.com"]
}- URL:
/api/v1/search/ - Метод:
GET - Требуется авторизация
- Параметры:
room_id(string) — идентификатор комнатыq(string) — поисковый запрос
Пример:
GET /api/v1/search/?room_id=!roomid:example.com&q=привет
Успешный ответ:
[
{
"event_id": "$uuid",
"json": {
"event_id": "$uuid",
"type": "m.text",
"sender": "@alice:example.com",
"content": {
"body": "Привет мир!",
"sender": "@alice:example.com"
}
}
}
]- URL:
/api/v1/editMessage/ - Метод:
POST - Требуется авторизация
- Редактировать можно только свои сообщения
Тело:
event_id(string) — идентификатор событияroom_id(string) — идентификатор комнатыbody(string) — новый текст сообщения
Пример тела запроса:
{
"event_id": "$uuid",
"room_id": "!roomid:example.com",
"body": "Исправленное сообщение"
}Успешный ответ:
{
"status": "ok"
}- URL:
/api/v1/directMessage/ - Метод:
POST - Требуется авторизация
Создаёт или возвращает существующий приватный диалог между двумя пользователями.
Тело:
user_id(string) — ID пользователя для диалога
Пример тела запроса:
{
"user_id": "@bob:example.com"
}Успешный ответ:
{
"status": "ok",
"room_id": "!uuid:example.com"
}