Справочник

REST API

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

Базовый URLhttps://storage.to/api
33 эндпоинта · JSON

Как работают загрузки

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

01 · POST /upload/init
Инициализация
сообщите, что хотите загрузить файл. Мы вернём один или несколько предподписанных URL-адресов, указывающих на наш storage edge.
02 · PUT {upload_url}
Загрузить
PUT ваши байты напрямую на presigned URL(ы). Байты не проходят через наши серверы.
03 · POST /upload/confirm
Подтвердить
сообщите, что загрузка завершена. Мы создадим запись File и дадим вам URL-адрес для общего доступа.

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

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

Анонимные загрузки работают без аутентификации, но с жесткими ограничениями. Вызовы без ключа ограничены 50 файлами за скользящие 24 часа на устройство или IP, плюс квоты трафика ниже, а файлы истекают через 3 дня.

Аутентификация с бесплатным аккаунтом открывает:

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

Лимиты вкратце

Без токена (анонимно)
Токен бесплатного аккаунта
Токен платного аккаунта
Файлов в день
50 / 24 часа
Без ограничений
Без ограничений
Объём загрузки
100 GB / 24 часа (500 GB на IP)
Без ограничений
Без ограничений
Максимальный размер файла
25 GB
25 GB
100 GB
Срок хранения файла
По умолчанию 3 дня, до 7 через expiry_days
По умолчанию 3 дня, до 7 через expiry_days
Никогда (файлы хранятся постоянно)
Хранилище
Нет (файлы удаляются по сроку)
Нет (файлы удаляются по сроку)
100 ГБ - 1 ТБ постоянного хранения, по тарифу
Смотреть тарифы →

Месячных квот нет: все лимиты - скользящие 24-часовые окна или ограничения в минуту. На бесплатном тарифе нет фиксированного хранилища: каждый файл удаляется по своему сроку, поэтому квота не накапливается.

Чтобы пройти аутентификацию, сгенерируйте персональный API-токен в своём аккаунте и отправляйте его как bearer-токен в каждом запросе: Вам нужно войти в аккаунт. Полный токен показывается только один раз при создании, поэтому сохраните его в надёжном месте. Токен можно отозвать в любое время на этой же странице. Сгенерировать API-токен →
Authorization: Bearer <token>

Подтверждение владения

Токен владельцаРекомендуется
Каждый endpoint, создающий ресурс (/upload/init multipart, /upload/confirm, /file/reserve, /collection), возвращает в ответе owner_token. Токен — это подписанное доказательство владения, привязанное к конкретному ресурсу, и не зависит от вашего IP или токена посетителя. Токены живут столько же, сколько существует ресурс, безопасны для хранения и не истекают независимо. Потеря токена означает потерю контроля над этим ресурсом (файл/коллекция/загрузка) — относитесь к ним как к локальным паролям.
Authorization: Owner <token>
# или вместе с сессией Bearer
X-Owner-Token: <token>
Токен посетителя
Анонимным клиентам нужен способ доказать, что именно они владеют своими загрузками, без аккаунта. Мы используем visitor token — случайную строку, которую клиент генерирует один раз и затем повторно использует. Отправляйте её с каждым запросом: В веб-версии токен автоматически сохраняется в cookie visitor_token. В CLI он хранится по адресу ~/.config/storageto/token (см. Документация для CLI).
X-Visitor-Token: <random-string>

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

Ошибки

Ошибки имеют единый формат: { "success": false, "error": "…" }

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 с подробностями. Это только лимит по загрузка - скачивания неограничены и без ограничений по скорости.

Загрузить

8 эндпоинтов

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

POST/upload/init60/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Только владелец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Только владелец500/min

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

Тело запроса

ПолеТипОписание
upload_idstring · requiredЗначение upload_id из /init.
partsarray · requiredКаждая запись: { partNumber, etag } из ответа на загрузку части.
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

Отменить multipart-загрузку и очистить любые частичные данные.

Тело запроса

ПолеТипОписание
upload_idstring · requiredЗагрузка, которую нужно прервать.
Request
curl -X POST https://storage.to/api/upload/abort \
  -H "Content-Type: application/json" \
  -d '{ "upload_id": "01HXYZ..." }'
POST/upload/confirm60/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",
    "filename": "report.pdf",
    "size": 2202009,
    "human_size": "2.1 MB",
    "expires_at": "2026-04-15T12:00:00Z"
  },
  "owner_token": "owner_v1_..."
}
POST/file/reserve60/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",
    "expires_at": "2026-04-12T18:00:00Z"
  },
  "owner_token": "owner_v1_..."
}

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

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

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

Коллекции

9 эндпоинтов

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

POST/collection30/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_..."
}

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

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Только владелец60/min

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

DELETE/collection/{id}Только владелец60/min

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

POST/collection/{id}/passwordТолько владелец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Только владелец30/min

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

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

Тело запроса

ПолеТипОписание
passwordstring · required
POST/collection/{id}/expiryТолько владелецБессрочно: платно30/min

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

Тело запроса

ПолеТипОписание
daysinteger · optionalЧерез 1–7 дней, но не позже 7 дней после загрузки (или текущего срока хранения, если он позже). Не указывайте или передайте null для бессрочного хранения (только премиум).
POST/collection/{id}/max-downloadsТолько владелец30/min

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

Тело запроса

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

Файлы

8 эндпоинтов

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

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

Response
{ "pending": false }
DELETE/file/{id}Только владелец60/min

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

POST/file/{id}/thumbnailТолько владелец120/min

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

Тело запроса

ПолеТипОписание
thumbnailimage · requiredMultipart-загрузка. Макс. 2 МБ.
Response
{
  "success": true,
  "thumbnail_url": "https://..."
}
POST/file/{id}/passwordТолько владелец30/min

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

DELETE/file/{id}/passwordТолько владелец30/min

Убрать пароль у файла.

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

POST/file/{id}/expiryТолько владелецБессрочно: платно30/min

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

Тело запроса

ПолеТипОписание
daysinteger · optionalЧерез 1–7 дней, но не позже 7 дней после загрузки (или текущего срока хранения, если он позже). Не указывайте или передайте null для бессрочного хранения (только премиум).
POST/file/{id}/max-downloadsТолько владелец30/min

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

Загрузка из ShareX

1 эндпоинт

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

POST/sharex/upload20/day

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

Request
curl -X POST https://storage.to/api/sharex/upload \
  -F "file=@screenshot.png"
Response
{
  "success": true,
  "url": "https://storage.to/FQxyz1234",
  "filename": "screenshot.png",
  "expires_at": "2026-04-15T12:00:00Z"
}

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

2 эндпоинта

Для клиентов с выполненным входом, например десктопного приложения, у которых есть токен Bearer.

GET/userТокен Bearer

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

Request
curl https://storage.to/api/user \
  -H "Authorization: Bearer <token>"
Response
{
  "id": 42,
  "name": "Ada",
  "email": "ada@example.com",
  "is_premium": true
}
POST/auth/logoutТокен Bearer

Отзовите текущий access token.

Разное

5 эндпоинтов

Состояние, квоты и телеметрия клиентов.

Проверка доступности. Возвращает 200 с { "status": "ok" }, когда воркер API обслуживает запросы.

Response
{ "status": "ok" }

Живой поток активности для «глобуса» на главной странице. Кэшируется на edge.

Текущее использование лимита загрузок для вызывающего — используется 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-analytics120/min

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

Тело запроса

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

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

Тело запроса

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