REST API

Загружайте файлы, создавайте коллекции и управляйте шарингом через HTTP. Все ответы в формате JSON; для анонимных загрузок API-ключ не требуется.

Введение

API storage.to работает в CLI, десктопное приложение, веб-загрузчик и любом стороннем клиенте, который вы захотите создать.

Процесс загрузки состоит из трёх шагов:

  1. Инициализация — сообщите, что хотите загрузить файл. Мы вернём один или несколько предварительно подписанных URL, указывающих на Cloudflare R2.
  2. Загрузка в R2PUT ваши байты напрямую на предварительно подписанный URL(ы). Байты не проходят через наши серверы.
  3. Подтверждение — сообщите, что загрузка завершена. Мы создадим запись File и выдадим вам ссылку для шаринга.

Базовый URL

https://storage.to/api

Все нижеперечисленные эндпоинты относительно этого базового URL. Пример: POST /upload/init означает POST https://storage.to/api/upload/init.

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

Большинство эндпоинтов не требуют аутентификации. Анонимные загрузки — ключевая функция.

Аутентификация необязательна и открывает:

  • Загрузки, привязанные к вашему аккаунту (видны в /dashboard)
  • Премиум-функции (постоянные файлы, больше места)
  • Изменения, основанные на владении (удаление, установка пароля, изменение срока действия) без необходимости совпадения visitor-token

Мы используем Laravel Sanctum bearer токены. Получите токен через OAuth в десктопном приложении или веб-входе, затем отправляйте его как:

Authorization: Bearer <token>

Visitor token

Анонимным клиентам нужен способ доказать владение своими загрузками без аккаунта. Мы используем visitor token — случайную строку, которую клиент генерирует один раз и повторно использует. Отправляйте её с каждым запросом:

X-Visitor-Token: <random-string>

В вебе токен автоматически хранится в cookie visitor_token. CLI сохраняет его в ~/.config/storageto/token (см. Документация CLI).

Для мутационных эндпоинтов (удаление, установка пароля, изменение срока) владение подтверждается, если либо visitor token совпадает или запрос приходит с того же IP, что создал файл.

Ошибки

Ошибки имеют единый формат:

{
  "success": false,
  "error": "Human-readable message"
}

Распространённые HTTP-коды статуса:

КодЗначение
200OK.
201Создано.
400Неверный запрос (например, превышен лимит размера коллекции).
401Требуется пароль или он неверен.
403Нет доступа (вы не владелец ресурса).
404Ресурс не найден или срок действия истёк.
422Ошибка валидации или ограничение плана/квоты.
429Превышен лимит запросов или квота загрузок.
500Ошибка сервера. Проверьте статус.

Ограничения скорости

Все ограничения скорости применяются на IP. Ответ с кодом 429 включает стандартные заголовки Retry-After, X-RateLimit-Limit и X-RateLimit-Remaining.

ОбластьЛимит
Инициация / подтверждение / отмена загрузки60 / минута
Завершение многокомпонентной загрузки500 / минута
URL частей многокомпонентной загрузки120 / минута
Инициация / подтверждение пакетной загрузки500 / минута
Опрос статуса (файл и коллекция)120 / минута
Настройки (пароль, срок действия, макс. загрузок)30 / минута
Проверка пароля10 / минута
Создание коллекции30 / минута
Управление (готово, удалить)60 / минута
Загрузка миниатюры120 / минута
Загрузка через ShareX20 / день
Аналитика приложения / ошибки120 и 60 / в минуту

Квота загрузки: Анонимные клиенты имеют два параллельных лимита — 100 ГБ / 24 ч на visitor token и 500 ГБ / 24 ч на IP (лимит по IP ловит трафик без токена и общие сети). При превышении любого из них вы получите 429 с деталями. Это только квота на загрузка — скачивания не ограничены и не замедляются (подаются напрямую с подписанных URL R2).

Загрузить

Трёхэтапный процесс загрузки для любых файлов, включая файлы больше 5 ГБ (автоматически многокомпонентная загрузка). Если нужна быстрая загрузка в стиле скриншота, используйте ShareX.

POST /upload/init 60/min

Инициализируйте загрузку. Для файлов >50 МБ в ответе есть part_urls для многокомпонентной загрузки; иначе один url.

Тело запроса

ПолеТипОписание
filenamestring · requiredОригинальное имя файла. Максимум 255 символов.
content_typestring · requiredMIME-тип.
sizeinteger · requiredРазмер файла в байтах. Минимум 1.
Request
curl -X POST https://storage.to/api/upload/init \ -H "Content-Type: application/json" \ -H "X-Visitor-Token: abc123" \ -d '{ "filename": "report.pdf", "content_type": "application/pdf", "size": 2202009 }'
Response · single upload
{ "success": true, "url": "https://r2.cloudflarestorage.com/...signed...", "r2_key": "uuid-abc123", "upload_id": null, "is_multipart": false }
Response · multipart
{ "success": true, "upload_id": "01HXYZ...", "r2_key": "uuid-abc123", "is_multipart": true, "part_size": 52428800, "part_urls": [ { "partNumber": 1, "url": "https://..." }, { "partNumber": 2, "url": "https://..." } ] }
POST /upload/parts 120/min

Запрос дополнительных URL частей для текущей многокомпонентной загрузки. Используется, если /init вернул меньше URL, чем частей у вас есть (или они истекли).

Тело запроса

ПолеТипОписание
upload_idstring · requiredupload_id из /init.
part_numbersarray<int> · requiredНомера частей для получения URL.
Request
curl -X POST https://storage.to/api/upload/parts \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ...", "part_numbers": [3, 4] }'
Response
{ "success": true, "part_urls": [ { "partNumber": 3, "url": "https://..." }, { "partNumber": 4, "url": "https://..." } ] }
POST /upload/complete-multipart 500/min

Завершите многокомпонентную загрузку на R2 после загрузки всех частей.

Тело запроса

ПолеТипОписание
upload_idstring · requiredupload_id из /init.
partsarray · requiredКаждая запись: { partNumber, etag } из ответа R2.
Request
curl -X POST https://storage.to/api/upload/complete-multipart \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ...", "parts": [ { "partNumber": 1, "etag": "\"abc...\"" }, { "partNumber": 2, "etag": "\"def...\"" } ] }'
Response
{ "success": true }
POST /upload/abort 60/min

Отмените многокомпонентную загрузку и удалите частичные данные на R2.

Тело запроса

ПолеТипОписание
upload_idstring · requiredЗагрузка для отмены.
Request
curl -X POST https://storage.to/api/upload/abort \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ..." }'
POST /upload/confirm 60/min

Подтвердите завершение загрузки. В этот момент создаётся запись File и возвращается ссылка для обмена.

Тело запроса

ПолеТипОписание
filenamestring · requiredОригинальное имя файла.
sizeinteger · requiredРазмер файла в байтах.
content_typestring · requiredMIME-тип.
r2_keystring · requiredr2_key из /init.
collection_idstring · optionalПрикрепить к коллекции.
crc32integer · optionalКонтрольная сумма CRC32 для проверки целостности.
file_idstring(9) · optionalВыполнить ранее зарезервировано ID файла.
Request
curl -X POST https://storage.to/api/upload/confirm \ -H "Content-Type: application/json" \ -H "X-Visitor-Token: abc123" \ -d '{ "filename": "report.pdf", "size": 2202009, "content_type": "application/pdf", "r2_key": "uuid-abc123" }'
Response
{ "success": true, "file": { "id": "FQxyz1234", "url": "https://storage.to/FQxyz1234", "raw_url": "https://storage.to/r/FQxyz1234", "filename": "report.pdf", "size": 2202009, "human_size": "2.1 MB", "expires_at": "2026-04-15T12:00:00Z" } }
POST /file/reserve 60/min

Зарезервируйте ID файла и ссылку для обмена до пока данные не готовы. Полезно, если нужно сначала выдать ссылку, а загрузку завершить позже. Право собственности привязано к вашему токену посетителя + IP. Завершите загрузку позже с помощью /upload/init + /upload/confirm, передав file_id для подтверждения.

Тело запроса

ПолеТипОписание
filenamestring · optionalИмя файла-заполнителя. По умолчанию "Pending".
content_typestring · optionalMIME-тип-заполнитель.
Request
curl -X POST https://storage.to/api/file/reserve \ -H "X-Visitor-Token: abc123"
Response
{ "success": true, "file": { "id": "FQxyz1234", "url": "https://storage.to/FQxyz1234", "raw_url": "https://storage.to/r/FQxyz1234", "expires_at": "2026-04-12T18:00:00Z" } }
POST /upload/init-batch 500/min

Пакетный эквивалент /upload/init, оптимизированный для веб-загрузчика. Инициирует до 250 файлов за один запрос.

Используется внутри веб-загрузчика. Большинству клиентов лучше использовать одиночный /upload/init.

POST /upload/confirm-batch 500/min

Пакетный эквивалент /upload/confirm. Подтверждает множество файлов за один запрос.

Коллекции

Коллекция объединяет несколько файлов под одной ссылкой для общего доступа (/c/{id}). До 10 000 файлов и 25 ГБ всего.

POST /collection 30/min

Создайте новую коллекцию. Добавляйте файлы позже, передавая collection_id на /upload/confirm.

Тело запроса

ПолеТипОписание
expected_file_countinteger · optionalПодсказка для автоматической отметки коллекции как готовой, когда все ожидаемые файлы подтверждены.
Request
curl -X POST https://storage.to/api/collection \ -H "Content-Type: application/json" \ -H "X-Visitor-Token: abc123" \ -d '{ "expected_file_count": 3 }'
Response
{ "success": true, "collection": { "id": "ABC123xyz", "url": "https://storage.to/c/ABC123xyz", "expires_at": "2026-04-15T12:00:00Z" } }
GET /collection/{id}/status 120/min

Опрашивает состояние коллекции. Также автоматически отмечает коллекцию как готовую, если все ожидаемые файлы подтверждены.

Request
curl https://storage.to/api/collection/ABC123xyz/status
Response
{ "success": true, "files": [ /* file objects: id, url, filename, size, ... */ ], "is_uploading": false, "file_count": 3, "expected_file_count": 3, "total_size": 6291456, "human_total_size": "6 MB" }
POST /collection/{id}/ready Owner only 60/min

Отметить коллекцию как готовую для скачивания. Обычно не требуется — коллекции автоматически становятся готовыми при достижении expected_file_count.

DELETE /collection/{id} Owner only 60/min

Удалить коллекцию и все её файлы.

POST /collection/{id}/password Owner only 30/min

Установить пароль на коллекцию. Требуется от 4 до 100 символов.

Тело запроса

ПолеТипОписание
passwordstring · requiredОт 4 до 100 символов.
Request
curl -X POST https://storage.to/api/collection/ABC123xyz/password \ -H "X-Visitor-Token: abc123" \ -d '{ "password": "hunter22" }'
DELETE /collection/{id}/password Owner only 30/min

Удалить пароль с коллекции.

POST /collection/{id}/verify-password 10/min

Проверить пароль. Возвращает 200 при успехе, 401 при неправильном пароле.

Тело запроса

ПолеТипОписание
passwordstring · required
POST /collection/{id}/expiry Owner only 30/min

Изменить срок действия коллекции.

Тело запроса

ПолеТипОписание
daysinteger · optionalОт 1 до 7 дней с текущего момента. Пропустите или укажите null для постоянного срока (только для премиум).
POST /collection/{id}/max-downloads Owner only 30/min

Установить ограничение на количество скачиваний (удаление после N скачиваний). Коллекция удаляется автоматически при достижении лимита.

Тело запроса

ПолеТипОписание
max_downloadsinteger · optionalОт 1 до 1000. Должно превышать текущее количество скачиваний. null для снятия ограничения.

Файлы

Все настройки на уровне файла (пароль, срок действия, макс. скачиваний) дублируют настройки коллекции. Только для владельца.

GET /file/{id}/status 120/min

Проверить, ожидает ли файл загрузки.

Response
{ "pending": false }
DELETE /file/{id} Owner only 60/min

Удалить файл немедленно.

POST /file/{id}/thumbnail Owner only 120/min

Загрузить миниатюру для видео или изображения (используется на странице скачивания). Максимум 2 МБ.

Тело запроса

ПолеТипОписание
thumbnailimage · requiredМногочастная загрузка. Максимум 2 МБ.
Response
{ "success": true, "thumbnail_url": "https://..." }
POST /file/{id}/password Owner only 30/min

Установить пароль на файл. Требуется от 4 до 100 символов.

DELETE /file/{id}/password Owner only 30/min

Удалить пароль с файла.

POST /file/{id}/verify-password 10/min

Проверить пароль файла.

POST /file/{id}/expiry Owner only 30/min

Изменить срок действия файла.

Тело запроса

ПолеТипОписание
daysinteger · optionalОт 1 до 7 дней с текущего момента. Пропустите или укажите null для постоянного срока (только для премиум).
POST /file/{id}/max-downloads Owner only 30/min

Ограничить общее количество скачиваний файла. Автоматическое удаление при достижении лимита.

Загрузка через ShareX

Одноразовый эндпоинт загрузки — отправьте многочастный файл и получите ссылку для общего доступа. Без этапов init/confirm. Идеально для инструментов скриншотов. Полное руководство по настройке на /ru/docs/sharex.

POST /sharex/upload 20/day

Загрузить изображение или файл напрямую (многочастная форма, поле file). Максимум 25 МБ.

Request
curl -X POST https://storage.to/api/sharex/upload \ -F "[email protected]"
Response
{ "success": true, "url": "https://storage.to/FQxyz1234", "raw_url": "https://storage.to/r/FQxyz1234", "filename": "screenshot.png", "expires_at": "2026-04-15T12:00:00Z" }

Авторизация на рабочем столе

Для аутентифицированных клиентов (например, настольного приложения) с токеном Sanctum.

GET /user Bearer token

Вернуть аутентифицированного пользователя.

Request
curl https://storage.to/api/user \ -H "Authorization: Bearer <token>"
Response
{ "id": 42, "name": "Ada", "email": "[email protected]", "is_premium": true }
POST /auth/logout Bearer token

Отозвать текущий токен доступа.

Разное

GET /health

Проверка состояния. Пингует базу данных, хранилище R2 и кеш Redis. Возвращает 200, если всё в порядке, иначе 503.

Response
{ "status": "healthy", "checks": { "database": "ok", "storage": "ok", "cache": "ok" }, "timestamp": "2026-04-12T12:00:00Z" }
GET /activity

Поток живой активности для глобуса на главной странице. Кэшируется на edge Cloudflare.

GET /bandwidth/status 60/min

Текущий расход квоты загрузки для вызывающего — используется CLI и настольным приложением для отображения оставшейся емкости. Форма ответа отличается для аутентифицированных пользователей. Несмотря на название URL, учитываются только загрузка байты; скачивания не считаются.

Response · anonymous
{ "success": true, "authenticated": false, "has_token": true, "limit_bytes": 107374182400, "limit_gb": 100, "used_bytes": 12345678, "used_gb": 0.01, "remaining_bytes": 107361836722, "remaining_gb": 99.99, "window_hours": 24 }
Response · authenticated
{ "success": true, "authenticated": true, "plan": "premium" }
POST /app-analytics 120/min

Отправить событие использования из CLI или настольного приложения.

Тело запроса

ПолеТипОписание
appstring · requireddesktop, cli или web.
versionstring · optionalВерсия клиента.
eventstring · requiredНазвание события, например upload_complete.
contextobject · optionalДополнительные метаданные.
POST /app-errors 60/min

Отправить отчёт об ошибке из CLI или настольного приложения. Удаление дубликатов на сервере — максимум 10 одинаковых ошибок в час.

Тело запроса

ПолеТипОписание
appstring · requireddesktop, cli или web.
typestring · requiredКласс/тип ошибки.
messagestring · requiredСообщение об ошибке.
stackstring · optionalСтек вызовов.
version, os, os_version, arch, contextvarious · optionalДиагностические метаданные.