⚠️ Внимание

  1. API находится в активной разработке
  2. Некоторые функции могут быть недоступны
  3. Документация может быть неактуальной
  4. Используйте на свой страх и риск

📖 Введение

MiCloud API предоставляет полный доступ к облачному хранилищу через HTTP REST интерфейс.

Base URL: https://api.micloud.website
Версия: v1
Сайты: https://micloud.website/sites

🔐 Аутентификация

Все запросы к API требуют API ключ в заголовке.

Получение API ключа

  1. Запустите команду /api_key в Telegram боте
  2. Бот выдаст уникальный ключ формата: user_id:token
  3. Сохраните ключ в безопасном месте

Варианты передачи ключа

Вариант 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.

Rate Limiting

Лимит: 60 запросов за 60 секунд (по IP).
Превышение лимита: HTTP 429 (Too Many Requests) — пример тела: {"error":"Rate limit exceeded"}.
Брутфорс-протекция: за многократные неудачные попытки IP может быть временно заблокирован.

Рекомендуется:

⚠️ Обработка ошибок

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":"..."}

Проверка сервера

GET/api/v1/ping

Описание: Получить ответ от сервера для проверки

✓ Ответ (200)

{"status": "ok", "message": "pong"}
# Пример curl curl -H "X-API-Key: YOUR_KEY" https://api.micloud.website/api/v1/pingА

📁 Дерево файлов и папок

GET/api/v1/tree

Описание: Получить полное дерево папок и файлов пользователя

✓ Параметры

Отсутствуют (аутентификация через 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 curl -H "X-API-Key: YOUR_KEY" https://api.micloud.website/api/v1/tree

📂 Содержимое папки

GET/api/v1/folder/{folder_id}

Описание: Получить содержимое конкретной папки (или корня, если 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

📤 Загрузка файла

POST/api/v1/files

Описание: Загрузить файл в облако (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 curl -H "X-API-Key: YOUR_KEY" \ -F "file=@/path/to/file.pdf" \ https://api.micloud.website/api/v1/files?folder_id=5

📥 Скачивание файла

GET/api/v1/files/{file_id}/download

Описание: Скачать файл по прямому 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

✏️ Переименование файла

PATCH/api/v1/files/{file_id}

Описание: Переименовать файл (скачивается, переи переупло жается в 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

🗑️ Удаление файла

DELETE/api/v1/files/{file_id}

Описание: Удалить файл

curl -X DELETE \ -H "X-API-Key: YOUR_KEY" \ https://api.micloud.website/api/v1/files/100

📁 Управление папками

Создание папки

POST/api/v1/folders

Описание: Создать новую папку

✓ 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

Переименование папки

PATCH/api/v1/folders/{folder_id}

✓ Body (JSON)

{"name": "Renamed Folder"}

🔗 Ссылки шаринга

Создание шаринг-ссылки

POST/api/v1/shares

Описание: Создать публичную ссылку на файл

✓ 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" }

Получение информации о шаринг-ссылке

GET/api/v1/shares/{share_id}
✓ Ответ (200):
{ "share_id": "abc123xyz", "file_id": 100, "owner_id": 123456, "password": null, "is_anonymous": 0, "clicks": 42 }
Примечание: если у ссылки установлен пароль — при запросе к этому endpoint требуется передать параметр ?pwd=PASSWORD (проверяется bcrypt).

Прямой доступ (по share_id)

GET/api/v1/share/{share_id}

Описание: Возвращает сам файл (attachment). Этот endpoint отдаёт прямой download по share_id — на текущий момент не требует передачи пароля в запросе.

✓ Успешный ответ (200): бинарные данные файла с заголовком Content-Disposition: attachment.
Примечание безопасности: ссылка-скачивания может обойти защиту паролем, если файл опубликован через прямой share; пересмотрите политику публикации при необходимости.

Обновление шаринг-ссылки

PATCH/api/v1/shares/{share_id}

Описание: Изменить пароль или флаг анонимности

✓ Body (JSON)

{ "password": "new_password", "is_anonymous": true }

Удаление шаринг-ссылки

DELETE/api/v1/shares/{share_id}

📚 Репозитории

Список репозиториев

GET/api/v1/repos

Описание: Получить все репозитории (созданные и где вы участник)

✓ Ответ (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 } ] }
GET/api/v1/repos/search

Описание: Поиск репозиториев по названию или 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"

Создание репозитория

POST/api/v1/repos

✓ Body (JSON)

{ "name": "My New Project", "description": "Optional description", "is_public": true }
✓ Ответ (200):
{"status":"created", "repo_id":"abc123"}

Получение информации о репозитории

GET/api/v1/repos/{repo_id}
✓ Ответ (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"} ] } }

Управление владельцем и членами репозитория

GET/api/v1/repos/{repo_id}/owner

Описание: Настройки владельца репозитория (доступны только владельцу).

{ "owner": { "user_id": 123456, "name": "John Doe", "email": "john@example.com" } }
GET/api/v1/repos/{repo_id}/members

Описание: Список членов репозитория (только owner или участник).

{ "members": [ { "user_id": 111, "full_name": "Alice", "role": "writer" } ] }
POST/api/v1/repos/{repo_id}/members

✓ Body (JSON)

{ "user_id": 222, "role": "reader" }
PATCH/api/v1/repos/{repo_id}/members/{user_id}

Описание: Обновить права члена (owner только).

DELETE/api/v1/repos/{repo_id}/members/{user_id}

Описание: Удалить участника из репозитория (owner только).

Получает список всех файлов, привязанных к указанному репозиторию.

GET/api/v1/repos/{repo_id}/files
✓ Ответ (200):
{"repo_id": "1325303090","files": [{"file_id": 42,"name": "index.html","size": 1540,"added_at": "2024-01-23 15:41:00", "icon": "📄"}]}

Обновление репозитория

PATCH/api/v1/repos/{repo_id}

✓ Body (JSON)

{ "name": "Updated Name", "description": "New description", "is_public": true, "is_published": false, "site_path": "username/projectname" }

Удаление репозитория

DELETE/api/v1/repos/{repo_id}

Описание: Удалить репозиторий и все его файлы (только создатель)

📄 Файлы в репозитории

Добавить файл в репозиторий

POST/api/v1/repos/{repo_id}/files

✓ Body (JSON)

{ "file_db_id": 100, // ID файла из /tree "message": "Added index.html" // опционально, сообщение коммита }

Удалить файл из репозитория

DELETE/api/v1/repos/{repo_id}/files/{file_id}

📦 Коммиты и версионирование

Система коммитов позволяет отслеживать историю изменений файлов в репозитории. При добавлении или удалении файла автоматически создаётся коммит.

Список коммитов репозитория

GET/api/v1/repos/{repo_id}/commits

Описание: Получить историю всех изменений в репозитории (макс. 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

Информация о конкретном коммите

GET/api/v1/repos/{repo_id}/commits/{commit_id}

Описание: Получить детальную информацию о коммите

✓ Ответ (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 }

Скачать файл из версии (коммита)

GET/api/v1/repos/{repo_id}/commits/{commit_id}/download

Описание: Получить file_id файла из конкретной версии для скачивания

✓ Ответ (200):
{ "file_id": "AgADBAADrq4AAA...", "file_name": "index.html", "commit_id": 42 }
Примечание: Используйте полученный file_id для скачивания файла через GET /api/v1/files/{file_id}/download
# 1. Получить file_id из коммита curl -H "X-API-Key: YOUR_KEY" \ https://api.micloud.website/api/v1/repos/abc123/commits/42/download # 2. Скачать файл используя file_id curl -H "X-API-Key: YOUR_KEY" \ https://api.micloud.website/api/v1/files/AgADBAADrq4AAA.../download \ -o index.html

🚀 Публикация сайтов

Получить статус публикации

GET/api/v1/repos/{repo_id}/deploy
✓ Ответ (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" }

Опубликовать/снять с публикации

POST/api/v1/repos/{repo_id}/deploy

✓ Body (JSON)

{ "action": "publish", // или "unpublish" "site_path": "username/projectname" // требуется для publish }
✓ Ответ (200):
{ "status": "ok", "site_url": "https://micloud.website/sites/username/projectname" }

👤 Текущий пользователь

GET/api/v1/me

Описание: Получить информацию о текущем пользователе (по API ключу)

✓ Ответ (200):
{ "user": { "user_id": 123456, "username": "john_doe", "full_name": "John Doe" } }
GET/api/v1/me/stats

Описание: Получить детальную статистику по использованию хранилища

✓ Ответ (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 ключ

POST/api/v1/api_key/regenerate

Описание: Создать новый API ключ (текущий будет переписан)

✓ Ответ (200):
{ "status": "regenerated", "api_key": "123456:long_token_string_here" }

📧 Почтовые ящики

Получить список ящиков

GET /api/v1/mailboxes

Описание: Получить все почтовые ящики пользователя

✓ Ответ (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 } ] }

Создать почтовый ящик

POST /api/v1/mailboxes

Описание: Создать новый почтовый ящик (максимум 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" } }

Удалить почтовый ящик

DELETE /api/v1/mailboxes/{mailbox_id}

Описание: Удалить ящик и все письма в нём

✓ Ответ (200)

{"status": "deleted"}

✉️ Письма

Получить письма в ящике

GET /api/v1/mailboxes/{mailbox_id}/mails?status={status}

Описание: Получить список писем

✓ 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" }

Получить конкретное письмо

GET /api/v1/mails/{mail_id}

Описание: Получить письмо по 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" } }

Отправить письмо

POST /api/v1/mailboxes/{mailbox_id}/send

Описание: Отправить письмо. Если получатель внутри системы 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" } }

Удалить письмо

DELETE /api/v1/mails/{mail_id}

Описание: Удалить письмо

✓ Ответ (200)

{"status": "deleted"}

Пометить как спам

POST /api/v1/mails/{mail_id}/spam

Описание: Переместить письмо в спам

✓ Ответ (200)

{"status": "marked_as_spam"}

🎮 Эвент

Статус ивента

GET /api/v1/event

Описание: Получить статус ивента и баланс пользователя

✓ Ответ (200)

{ "event": { "active": true, "currency": "💾", "box_price": 5 }, "balance": { "current_coins": 12, "total_earned": 45 }, "active_boxes": 2 }

📦 Лутбоксы

Список ящиков

GET /api/v1/event/boxes

Описание: Получить все ящики пользователя

✓ Ответ (200)

{ "boxes": [ { "box_id": "a1b2c3d4e5f6", "taps_left": 3, "status": "active", "rarity": "common", "created_at": "2026-01-25 12:00:00" } ] }

Купить ящик

POST /api/v1/event/boxes

Описание: Купить лутбокс за валюту ивента

Требования

  • Ивент должен быть активен
  • На балансе должно быть достаточно валюты (box_price)

✓ Ответ (201)

{ "status": "created", "box": { "box_id": "a1b2c3d4e5f6", "taps_left": 4, "rarity": "common" }, "new_balance": 7 }

Удар по ящику (вскрытие)

POST /api/v1/event/boxes/{box_id}/tap

Описание: Ударить по ящику. После 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 примеры

# 1. Получить информацию о пользователе curl -H "X-API-Key: YOUR_KEY" https://api.micloud.website/api/v1/me # 2. Загрузить файл curl -H "X-API-Key: YOUR_KEY" \ -F "file=@document.pdf" \ https://api.micloud.website/api/v1/files?folder_id=5 # 3. Скачать файл curl -H "X-API-Key: YOUR_KEY" \ -O https://api.micloud.website/api/v1/files/100/download # 4. Создать репозиторий 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 # 5. Получить дерево файлов 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} # 1. Получить информацию о пользователе response = requests.get(f"{BASE_URL}/me", headers=HEADERS) print(response.json()) # 2. Загрузить файл 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()) # 3. Получить дерево файлов response = requests.get(f"{BASE_URL}/tree", headers=HEADERS) tree = response.json() print(json.dumps(tree, indent=2)) # 4. Создать репозиторий 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()) # 5. Скачать файл 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) перед продакшеном