REST API

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

Введение

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

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

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

Базовый URL

https://storage.to/api

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

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

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

Аутентификация необязательна и даёт доступ к:

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

Чтобы пройти аутентификацию, сгенерируйте персональный API-токен в своём аккаунте и отправляйте его как bearer-токен в каждом запросе:

Authorization: Bearer <token>

Сгенерировать API-токен

Вам нужно войти в аккаунт. Полный токен показывается только один раз при создании, поэтому сохраните его в надёжном месте. Токен можно отозвать в любое время на этой же странице.

Токен посетителя

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

X-Visitor-Token: <random-string>

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

Для мутационных endpoint’ов (удаление, установка пароля, изменение срока действия) владение подтверждается, если либо токен посетителя совпадает или запрос приходит с того же IP, с которого был создан файл. Оба варианта могут быть потеряны (очищенные cookies, смена сети). В дальнейшем предпочтительным доказательством является owner token.

Токен владельца

Каждый endpoint, создающий ресурс (/upload/init multipart, /upload/confirm, /upload/reserve, /collection), возвращает в ответе owner_token. Токен — это подписанное доказательство владения, привязанное к конкретному ресурсу, и не зависит от вашего IP или токена посетителя.

Сохраните токен вместе с ID ресурса и отправляйте его в любом запросе на изменение как:

Authorization: Owner <token>

Или, если вы уже используете Authorization: Bearer для аутентифицированной сессии, отправляйте его так:

X-Owner-Token: <token>

Сервер принимает owner token как действительное доказательство владения вместе с устаревшим вариантом visitor token + запасной IP — клиенты, у которых есть токен, продолжают работать после смены сети или очистки cookies, а клиенты без токена продолжают работать ровно как раньше.

Токены живут столько же, сколько существует ресурс, безопасны для хранения и не истекают независимо. Потеря токена означает потерю контроля над этим ресурсом (файл/коллекция/загрузка) — относитесь к ним как к локальным паролям.

Ошибки

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

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

Частые HTTP-коды состояния:

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

Ограничения по частоте запросов

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

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

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

Загрузить

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

POST /upload/init 60/min

Инициируйте загрузку. Для файлов >50 МБ ответ будет multipart-загрузкой (поле type: "multipart"); иначе — один presigned PUT.

Тело запроса

ПолеТипОписание
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, "type": "single", "upload_url": "https://r2.cloudflarestorage.com/...signed...", "headers": { "Host": ["..."] }, "r2_key": "uuid-abc123" }
Response · multipart
{ "success": true, "type": "multipart", "upload_id": "01HXYZ...", "r2_key": "uuid-abc123", "part_size": 33554432, "total_parts": 4, "initial_urls": { "1": "https://...", "2": "https://..." }, "owner_token": "owner_v1_..." }
POST /upload/parts Owner only 120/min

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

Тело запроса

ПолеТипОписание
upload_idstring · requiredЗначение upload_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 Owner only 500/min

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

Тело запроса

ПолеТипОписание
upload_idstring · requiredЗначение upload_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 Owner only 60/min

Отменить multipart-загрузку и очистить любые частичные данные на 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 и возвращаем общий URL.

Тело запроса

ПолеТипОписание
filenamestring · requiredОригинальное имя файла.
sizeinteger · requiredРазмер файла в байтах.
content_typestring · requiredMIME-тип.
r2_keystring · requiredЗначение r2_key из /init.
collection_idstring · optionalДобавить в коллекцию.
crc32integer · optionalКонтрольная сумма CRC32 для проверки целостности.
file_idstring(9) · optionalВыполнить (fulfil) ранее выданный reserved file 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" }, "owner_token": "owner_v1_..." }
POST /file/reserve 60/min

Зарезервируйте file ID и общий URL до того, как будут готовы байты. Удобно, когда нужно сначала выдать ссылку, а затем выполнить загрузку. Владение привязано к вашему visitor token + 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" }, "owner_token": "owner_v1_..." }
POST /upload/init-batch 500/min

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

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

POST /upload/confirm-batch 500/min

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

Коллекции

Коллекция объединяет несколько файлов под одним общим URL (/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" }, "owner_token": "owner_v1_..." }
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 · required4–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 для постоянного (только premium).
POST /collection/{id}/max-downloads Owner only 30/min

Установить лимит скачиваний (burn-after-N-downloads). Коллекция автоматически удалится, когда лимит будет достигнут.

Тело запроса

ПолеТипОписание
max_downloadsinteger · optional1–1000. Должно быть больше текущего количества скачиваний. null — чтобы убрать лимит.

Файлы

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

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 · requiredMultipart-загрузка. Макс. 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 для постоянного (только premium).
POST /file/{id}/max-downloads Owner only 30/min

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

Загрузка из ShareX

Одноразовая точка загрузки — отправьте multipart-файл и получите обратно URL, которым можно делиться. Никаких инициализаций/подтверждений. Идеально для инструментов скриншотов. Полная инструкция по настройке: /ru/docs/sharex.

POST /sharex/upload 20/day

Загрузить изображение или файл напрямую (multipart form, поле 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" }

Аутентификация для десктопа

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

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

Отзовите текущий access 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 или desktop-приложения.

Тело запроса

ПолеТипОписание
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Диагностические метаданные.
Недавние загрузки
Нет недавних загрузок.

This list only lives on this browser.

Create a free account to find your files anywhere →