⚠️ Внимание
- API находится в активной разработке
- Некоторые функции могут быть недоступны
- Документация может быть неактуальной
- Используйте на свой страх и риск
📖 Введение
MiCloud API предоставляет полный доступ к облачному хранилищу через
HTTP REST интерфейс.
Base URL: https://api.micloud.website
Версия: v1
Сайты: https://micloud.website/sites
🔐 Аутентификация
Все запросы к API требуют API ключ в заголовке.
Получение API ключа
- Запустите команду
/api_key в Telegram боте
-
Бот выдаст уникальный ключ формата:
user_id:token
- Сохраните ключ в безопасном месте
Варианты передачи ключа
Вариант 1: Заголовок X-API-Key (рекомендуется)
curl -H "X-API-Key: YOUR_API_KEY"
https://api.micloud.website/api/v1/me
Вариант 2: Authorization заголовок
curl -H "Authorization: ApiKey YOUR_API_KEY"
https://api.micloud.website/api/v1/me
🌐 CORS & Rate Limiting
CORS (Cross-Origin Resource Sharing)
По умолчанию сервер возвращает заголовок Access-Control-Allow-Origin: * (разрешены все источники). Для безопасности в продакшне рекомендуется ограничивать origin на уровне прокси/NGINX.
- Часто используемые origin: https://micloud.website, https://www.micloud.website
- Локальное тестирование: http://127.0.0.1:8080
Rate Limiting
Лимит: 60 запросов за 60 секунд (по IP).
Превышение лимита: HTTP 429 (Too Many Requests) — пример тела: {"error":"Rate limit exceeded"}.
Брутфорс-протекция: за многократные неудачные попытки IP может быть временно заблокирован.
Рекомендуется:
- Группировать запросы где возможно
- Реализовать exponential backoff в клиенте
-
Использовать Redis для синхронизации лимитов (для масштабирования)
⚠️ Обработка ошибок
API возвращает JSON с полем error и соответствующий
HTTP статус код.
| Статус |
Описание |
Пример |
| 400 |
Bad Request (ошибка в параметрах) |
{"error":"name required"} |
| 401 |
Unauthorized (неверный/отсутствует API ключ) |
{"error":"Unauthorized"} |
| 403 |
Forbidden (нет доступа) |
{"error":"Forbidden"} |
| 404 |
Not Found (ресурс не найден) |
{"error":"Not found"} |
| 413 |
Payload Too Large (размер файла превышает лимит) |
{"error":"File size exceeds limit (500.0MB)"} |
| 429 |
Too Many Requests (превышен лимит) |
{"error":"Rate limit exceeded"} |
| 500 |
Internal Server Error |
{"error":"..."} |
Проверка сервера
Описание: Получить ответ от сервера для проверки
✓ Ответ (200)
{"status": "ok", "message": "pong"}
curl -H "X-API-Key: YOUR_KEY"
https://api.micloud.website/api/v1/pingА
📁 Дерево файлов и папок
Описание: Получить полное дерево папок и файлов
пользователя
✓ Параметры
Отсутствуют (аутентификация через API ключ)
✓ Ответ (200)
{ "owner": { "user_id": 123456, "username": "john_doe",
"full_name": "John Doe" }, "tree": { "folders": [ { "id": 1,
"name": "Projects", "children": { "folders": [...], "files":
[...] } } ], "files": [ { "id": 100, "name": "document.pdf",
"size": 1024000 } ] } }
curl -H "X-API-Key: YOUR_KEY"
https://api.micloud.website/api/v1/tree
📂 Содержимое папки
Описание: Получить содержимое конкретной папки
(или корня, если folder_id=root)
✓ Параметры пути
| Параметр |
Тип |
Описание |
| folder_id |
integer | string "root" |
ID папки или "root" для корня |
curl -H "X-API-Key: YOUR_KEY"
https://api.micloud.website/api/v1/folder/root curl -H "X-API-Key:
YOUR_KEY" https://api.micloud.website/api/v1/folder/5
📤 Загрузка файла
Описание: Загрузить файл в облако
(multipart/form-data)
✓ Query параметры (опционально)
| Параметр |
Тип |
Описание |
| folder_id |
integer |
ID папки для загрузки (если не передан — в корень) |
✓ Body (multipart/form-data)
| Поле |
Тип |
Описание |
| file |
file (binary) |
Бинарные данные файла |
✓ Успешный ответ (200):
{"status":"uploaded", "file":"document.pdf", "size": 1024000}
✓ Ограничения и возможные ошибки
- Максимальный размер файла: 500 MB — при превышении возвращается
413 Payload Too Large (пример: {"error":"File size exceeds limit (500.0MB)"}).
- Чанк: сервер читает по 10 MB за итерацию (защитная настройка).
- Запрещённые расширения: исполняемые/серверные файлы (php, py, sh, exe, dll, jar и т.п.) — при попытке загрузки возвращается
403.
- Лимит загрузок: 5 загрузок / 60 сек. на пользователя — при превышении
429.
- Пустой файл —
400, обнаружение исполняемого кода внутри файла — 403.
curl -H "X-API-Key: YOUR_KEY" \ -F "file=@/path/to/file.pdf" \
https://api.micloud.website/api/v1/files?folder_id=5
📥 Скачивание файла
Описание: Скачать файл по прямому URL (с
заголовком Content-Disposition)
✓ Параметры пути
| Параметр |
Описание |
| file_id |
ID файла (из /tree или /folder) |
✓ Успешный ответ (200): Бинарные данные файла с
заголовками:
Content-Type: application/pdf Content-Disposition: attachment;
filename="document.pdf"
curl -H "X-API-Key: YOUR_KEY" \ -O
https://api.micloud.website/api/v1/files/100/download
✏️ Переименование файла
Описание: Переименовать файл (скачивается, переи
переупло жается в Telegram)
✓ Body (JSON)
{"name": "new_document.pdf"}
curl -X PATCH \ -H "X-API-Key: YOUR_KEY" \ -H "Content-Type:
application/json" \ -d '{"name":"new_name.txt"}' \
https://api.micloud.website/api/v1/files/100
🗑️ Удаление файла
Описание: Удалить файл
curl -X DELETE \ -H "X-API-Key: YOUR_KEY" \
https://api.micloud.website/api/v1/files/100
📁 Управление папками
Создание папки
Описание: Создать новую папку
✓ Body (JSON)
{ "name": "My Project", "parent_id": null // null = корень, или
ID родительской папки }
curl -X POST \ -H "X-API-Key: YOUR_KEY" \ -H "Content-Type:
application/json" \ -d '{"name":"New Folder"}' \
https://api.micloud.website/api/v1/folders
Переименование папки
✓ Body (JSON)
{"name": "Renamed Folder"}
🔗 Ссылки шаринга
Создание шаринг-ссылки
Описание: Создать публичную ссылку на файл
✓ Body (JSON)
{ "file_id": 100, "password": "optional_password", //
опционально (только для Premium) "is_anonymous": false //
опционально }
✓ Ответ (200):
{ "status": "created", "share_id": "abc123xyz", "link":
"https://t.me/micloud_bot?start=abc123xyz" }
Получение информации о шаринг-ссылке
✓ Ответ (200):
{ "share_id": "abc123xyz", "file_id": 100, "owner_id": 123456,
"password": null, "is_anonymous": 0, "clicks": 42 }
Примечание: если у ссылки установлен пароль — при запросе к этому endpoint требуется передать параметр ?pwd=PASSWORD (проверяется bcrypt).
Прямой доступ (по share_id)
Описание: Возвращает сам файл (attachment). Этот endpoint отдаёт прямой download по share_id — на текущий момент не требует передачи пароля в запросе.
✓ Успешный ответ (200): бинарные данные файла с заголовком Content-Disposition: attachment.
Примечание безопасности: ссылка-скачивания может обойти защиту паролем, если файл опубликован через прямой share; пересмотрите политику публикации при необходимости.
Обновление шаринг-ссылки
Описание: Изменить пароль или флаг анонимности
✓ Body (JSON)
{ "password": "new_password", "is_anonymous": true }
Удаление шаринг-ссылки
📚 Репозитории
Список репозиториев
Описание: Получить все репозитории (созданные и
где вы участник)
✓ Ответ (200):
{ "repos": [ { "repo_id": "abc123", "name": "My Project",
"creator_id": 123456, "description": "Project description",
"is_public": 1, "is_published": 0, "site_path": null,
"subdomain": null } ] }
Поиск репозиториев
Описание: Поиск репозиториев по названию или ID.
Возвращает публичные репозитории и ваши приватные.
🔧 Query параметры:
q=запрос&limit=10
- q - поисковый запрос (название или ID репозитория)
- limit - лимит результатов (максимум 50, по умолчанию 10)
✓ Ответ (200):
{ "repos": [ { "repo_id": "abc123", "name": "My Project",
"description": "Project description", "creator_id": 123456,
"is_public": true, "is_verified": false, "is_frozen": false,
"emoji_icon": "📔", "created_at": "2026-02-18T10:30:00",
"creator_name": "John Doe", "creator_username": "johndoe" } ],
"query": "my project", "total": 1, "limit": 10 }
curl -H "X-API-Key: YOUR_KEY" \
"https://api.micloud.website/api/v1/repos/search?q=myproject&limit=5"
Создание репозитория
✓ Body (JSON)
{ "name": "My New Project", "description": "Optional
description", "is_public": true }
✓ Ответ (200):
{"status":"created", "repo_id":"abc123"}
Получение информации о репозитории
✓ Ответ (200):
{ "repo": { "repo_id": "abc123", "creator_id": 123456, "name":
"My Project", "description": "...", "is_public": 1,
"is_published": 0, "site_path": null, "subdomain": null,
"file_count": 5, "total_size": 1048576, "members": [ {"user_id":
123456, "full_name": "John Doe", "role": "owner"} ] } }
Управление владельцем и членами репозитория
Описание: Настройки владельца репозитория (доступны только владельцу).
{ "owner": { "user_id": 123456, "name": "John Doe", "email": "john@example.com" } }
Описание: Список членов репозитория (только owner или участник).
{ "members": [ { "user_id": 111, "full_name": "Alice", "role": "writer" } ] }
✓ Body (JSON)
{ "user_id": 222, "role": "reader" }
Описание: Обновить права члена (owner только).
Описание: Удалить участника из репозитория (owner только).
Получает список всех файлов, привязанных к указанному репозиторию.
✓ Ответ (200):
{"repo_id": "1325303090","files": [{"file_id": 42,"name":
"index.html","size": 1540,"added_at": "2024-01-23 15:41:00",
"icon": "📄"}]}
Обновление репозитория
✓ Body (JSON)
{ "name": "Updated Name", "description": "New description",
"is_public": true, "is_published": false, "site_path":
"username/projectname" }
Удаление репозитория
Описание: Удалить репозиторий и все его файлы
(только создатель)
📄 Файлы в репозитории
Добавить файл в репозиторий
✓ Body (JSON)
{ "file_db_id": 100, // ID файла из /tree "message": "Added
index.html" // опционально, сообщение коммита }
Удалить файл из репозитория
📦 Коммиты и версионирование
Система коммитов позволяет отслеживать историю изменений файлов в
репозитории. При добавлении или удалении файла автоматически
создаётся коммит.
Список коммитов репозитория
Описание: Получить историю всех изменений в
репозитории (макс. 100 последних коммитов)
✓ Ответ (200):
{ "commits": [ { "commit_id": 42, "file_id":
"AgADBAADrq4AAA...", "file_name": "index.html", "action":
"added", "message": "Added via API", "timestamp":
"2026-01-24T12:00:00", "user_id": 123456 }, { "commit_id": 41,
"file_id": "AgADBAADrq4AAA...", "file_name": "style.css",
"action": "removed", "message": "Removed old style",
"timestamp": "2026-01-24T11:30:00", "user_id": 123456 } ],
"count": 2 }
curl -H "X-API-Key: YOUR_KEY"
https://api.micloud.website/api/v1/repos/abc123/commits
Информация о конкретном коммите
Описание: Получить детальную информацию о коммите
✓ Ответ (200):
{ "commit_id": 42, "repo_id": "abc123", "file_id":
"AgADBAADrq4AAA...", "file_name": "index.html", "action":
"added", "message": "Added via API", "timestamp":
"2026-01-24T12:00:00", "user_id": 123456 }
Скачать файл из версии (коммита)
Описание: Получить file_id файла из конкретной
версии для скачивания
✓ Ответ (200):
{ "file_id": "AgADBAADrq4AAA...", "file_name": "index.html",
"commit_id": 42 }
Примечание: Используйте полученный file_id для
скачивания файла через GET /api/v1/files/{file_id}/download
curl -H "X-API-Key: YOUR_KEY" \
https://api.micloud.website/api/v1/repos/abc123/commits/42/download
curl -H "X-API-Key: YOUR_KEY" \
https://api.micloud.website/api/v1/files/AgADBAADrq4AAA.../download
\ -o index.html
🚀 Публикация сайтов
Получить статус публикации
✓ Ответ (200):
{ "repo_id": "abc123", "is_published": 1, "site_path":
"john_doe/my_project", "subdomain": null, "site_url":
"https://micloud.website/sites/john_doe/my_project" }
Опубликовать/снять с публикации
✓ Body (JSON)
{ "action": "publish", // или "unpublish" "site_path":
"username/projectname" // требуется для publish }
✓ Ответ (200):
{ "status": "ok", "site_url":
"https://micloud.website/sites/username/projectname" }
👤 Текущий пользователь
Описание: Получить информацию о текущем
пользователе (по API ключу)
✓ Ответ (200):
{ "user": { "user_id": 123456, "username": "john_doe",
"full_name": "John Doe" } }
Описание: Получить детальную статистику по
использованию хранилища
✓ Ответ (200):
{ "user_id": 123456, "stats": { "files_count": 12,
"repos_count": 3, "used_storage_mb": 4.5, "limit_mb": 100,
"usage_percent": 4.5, "is_premium": true, "subscription_end":
"2026-02-25T10:30:00" } }
🔑 API ключ
Описание: Создать новый API ключ (текущий будет
переписан)
✓ Ответ (200):
{ "status": "regenerated", "api_key":
"123456:long_token_string_here" }
📧 Почтовые ящики
Получить список ящиков
Описание: Получить все почтовые ящики пользователя
✓ Ответ (200)
{
"mailboxes": [
{
"id": 1,
"email": "myname//:minmail",
"is_active": true,
"is_spam": false,
"created_date": "2026-01-25 12:00:00",
"inbox_count": 5,
"unread_count": 2
}
]
}
Создать почтовый ящик
Описание: Создать новый почтовый ящик (максимум 5 на пользователя)
✓ Body (JSON)
{"name": "myname"}
Ограничения
- Минимум 3 символа в имени
- Только латинские буквы, цифры, _ и -
- Максимум 5 ящиков на пользователя
- Формат адреса:
имя//:minmail
✓ Ответ (201)
{
"status": "created",
"mailbox": {
"id": 2,
"email": "myname//:minmail",
"created_date": "2026-01-25 14:30:00"
}
}
Удалить почтовый ящик
Описание: Удалить ящик и все письма в нём
✓ Ответ (200)
{"status": "deleted"}
✉️ Письма
Получить письма в ящике
Описание: Получить список писем
✓ Query параметры
| Параметр |
Значения |
По умолчанию |
| status |
inbox, sent, spam |
inbox |
✓ Ответ (200)
{
"mails": [
{
"id": 1,
"from_email": "sender//:minmail",
"subject": "Привет!",
"body": "Текст письма...",
"is_read": false,
"created_date": "2026-01-25 15:00:00"
}
],
"status": "inbox"
}
Получить конкретное письмо
Описание: Получить письмо по ID (автоматически помечает как прочитанное)
✓ Ответ (200)
{
"mail": {
"id": 1,
"from_email": "sender//:minmail",
"to_email": "myname//:minmail",
"subject": "Привет!",
"body": "Текст письма...",
"is_read": true,
"status": "inbox",
"created_date": "2026-01-25 15:00:00"
}
}
Отправить письмо
Описание: Отправить письмо. Если получатель внутри системы minmail - доставляется мгновенно.
✓ Body (JSON)
{
"to": "recipient//:minmail",
"subject": "Тема письма",
"body": "Текст письма..."
}
✓ Ответ (200)
{
"status": "sent",
"mail": {
"id": 5,
"to_email": "recipient//:minmail",
"subject": "Тема письма",
"created_date": "2026-01-25 16:00:00"
}
}
Удалить письмо
Описание: Удалить письмо
✓ Ответ (200)
{"status": "deleted"}
Пометить как спам
Описание: Переместить письмо в спам
✓ Ответ (200)
{"status": "marked_as_spam"}
🎮 Эвент
Статус ивента
Описание: Получить статус ивента и баланс пользователя
✓ Ответ (200)
{
"event": {
"active": true,
"currency": "💾",
"box_price": 5
},
"balance": {
"current_coins": 12,
"total_earned": 45
},
"active_boxes": 2
}
📦 Лутбоксы
Список ящиков
Описание: Получить все ящики пользователя
✓ Ответ (200)
{
"boxes": [
{
"box_id": "a1b2c3d4e5f6",
"taps_left": 3,
"status": "active",
"rarity": "common",
"created_at": "2026-01-25 12:00:00"
}
]
}
Купить ящик
Описание: Купить лутбокс за валюту ивента
Требования
- Ивент должен быть активен
- На балансе должно быть достаточно валюты (box_price)
✓ Ответ (201)
{
"status": "created",
"box": {
"box_id": "a1b2c3d4e5f6",
"taps_left": 4,
"rarity": "common"
},
"new_balance": 7
}
Удар по ящику (вскрытие)
Описание: Ударить по ящику. После 4 ударов - открывается.
Механика
- При каждом ударе есть 25% шанс повышения редкости
- Rarity: common → rare → epic → legendary
- Когда taps_left = 0, ящик открывается и выдаёт награду
✓ Ответ (200) - Удар
{
"status": "tap",
"taps_left": 2,
"rarity": "rare",
"upgrade_happened": true,
"opened": false
}
✓ Ответ (200) - Открытие
{
"status": "opened",
"rarity": "legendary",
"reward": {
"type": "premium",
"days": 7
},
"opened": true
}
Reward type может быть: coins (с полем amount) или premium (с полем days)
💻 Примеры использования
curl примеры
curl -H "X-API-Key: YOUR_KEY" https://api.micloud.website/api/v1/me
curl -H "X-API-Key: YOUR_KEY" \ -F "file=@document.pdf" \
https://api.micloud.website/api/v1/files?folder_id=5
curl -H "X-API-Key: YOUR_KEY" \ -O
https://api.micloud.website/api/v1/files/100/download
curl -X POST \ -H "X-API-Key: YOUR_KEY" \ -H "Content-Type:
application/json" \ -d '{"name":"My Repo","is_public":true}' \
https://api.micloud.website/api/v1/repos
curl -H "X-API-Key: YOUR_KEY"
https://api.micloud.website/api/v1/tree
Python примеры
import requests import json API_KEY = "your_api_key_here" BASE_URL =
"https://api.micloud.website/api/v1" HEADERS = {"X-API-Key":
API_KEY}
response = requests.get(f"{BASE_URL}/me", headers=HEADERS)
print(response.json())
with open("document.pdf", "rb") as f: files = {"file": f} response =
requests.post( f"{BASE_URL}/files?folder_id=5", headers=HEADERS,
files=files ) print(response.json())
response = requests.get(f"{BASE_URL}/tree", headers=HEADERS) tree =
response.json() print(json.dumps(tree, indent=2))
data = { "name": "My New Project", "description": "Test project",
"is_public": True } response = requests.post( f"{BASE_URL}/repos",
headers=HEADERS, json=data ) print(response.json())
response = requests.get( f"{BASE_URL}/files/100/download",
headers=HEADERS ) with open("downloaded.pdf", "wb") as f:
f.write(response.content)
📋 Дополнительные рекомендации
Безопасность
- Всегда используйте HTTPS в продакшене
- Храните API ключи в переменных окружения, не в коде
- Регулярно переиздавайте ключи (POST /api_key/regenerate)
- Используйте разные ключи для разных приложений
- Логируйте и мониторьте использование API
Лучшие практики
- Группируйте запросы где возможно для снижения нагрузки
- Реализуйте exponential backoff для обработки 429 ошибок
- Кэшируйте данные на клиенте (особенно /tree)
- Используйте webhook вместо полинга где возможно
-
Тестируйте с локальным IP (http://127.0.0.1:8080) перед
продакшеном