Referencje

REST API

Wysyłaj pliki, twórz kolekcje i zarządzaj udostępnieniami przez HTTP. Wszystkie odpowiedzi są w formacie JSON; do anonimowych wysyłek nie jest wymagany klucz API.

Adres bazowy (Base URL)https://storage.to/api
33 endpointy · JSON

Jak działa wysyłanie plików

API storage.to napędza nasze CLI, aplikacja desktopowa, aplikacja do wysyłania w przeglądarce oraz każdy klient zewnętrzny, który chcesz zbudować. Proces wysyłania składa się z trzech kroków:

01 · POST /upload/init
Inicjuj
powiedz nam, że chcesz wysłać plik. Zwracamy jeden lub więcej presigned URLi wskazujących na nasz edge magazynowania.
02 · PUT {upload_url}
Upload
PUT swoje bajty bezpośrednio na presigned URL(e). Bajty nie przechodzą przez nasze serwery.
03 · POST /upload/confirm
Potwierdź
daj nam znać, że wysyłka się zakończyła. Tworzymy rekord File i przekazujemy Ci URL do udostępnienia.

Wszystkie endpointy poniżej są względne względem tej bazy. Przykład: POST /upload/init oznacza POST https://storage.to/api/upload/init.

Uwierzytelnianie

Anonimowe przesyłanie działa bez uwierzytelniania, ale z rygorystycznymi limitami. Wywołania bez klucza są ograniczone do 50 plików na kroczące 24 godziny na urządzenie lub IP, plus poniższe limity przepustowości, a pliki wygasają po 3 dniach.

Uwierzytelnienie darmowym kontem odblokowuje:

  • Bez dziennego limitu plików
  • Brak limitu przepustowości wysyłania
  • Wysyłki przypisane do Twojego konta (widoczne w /dashboard)
  • Funkcje premium (pliki na stałe, większa przestrzeń)
  • Zmiany oparte na własności (usuń, ustaw hasło, zmień datę ważności) bez konieczności dopasowania visitor-token

Limity w skrócie

Bez tokenu (anonimowo)
Token darmowego konta
Token płatnego konta
Plików dziennie
50 / 24 godz.
Bez limitu
Bez limitu
Przepustowość wysyłania
100 GB / 24 godz. (500 GB na IP)
Bez limitu
Bez limitu
Maks. rozmiar pliku
25 GB
25 GB
100 GB
Wygasanie pliku
Domyślnie 3 dni, do 7 przez expiry_days
Domyślnie 3 dni, do 7 przez expiry_days
Nigdy (pliki są trwałe)
Przestrzeń dyskowa
Brak (pliki wygasają)
Brak (pliki wygasają)
100 GB - 1 TB na stałe, zależnie od planu
Zobacz plany →

Nie ma miesięcznych limitów - wszystkie limity to kroczące okna 24-godzinne lub limity na minutę. Darmowy plan nie ma stałej przestrzeni dyskowej: każdy plik wygasa sam, więc nic nie kumuluje się w ramach limitu.

Aby się uwierzytelnić, wygeneruj osobisty token API z konta i wysyłaj go jako token typu bearer w każdym żądaniu: Musisz być zalogowany. Pełny token jest pokazany tylko raz podczas tworzenia — skopiuj go w bezpieczne miejsce. Możesz unieważnić token w dowolnym momencie na tej samej stronie. Wygeneruj token API →
Authorization: Bearer <token>

Potwierdzanie własności

Token właścicielaZalecane
Każdy endpoint tworzący zasób (/upload/init multipart, /upload/confirm, /file/reserve, /collection) zwraca w odpowiedzi owner_token. Token jest podpisanym dowodem własności przypisanym do konkretnego zasobu, niezależnym od Twojego IP ani tokenu odwiedzającego. Tokeny działają tak długo, jak istnieje zasób, są bezpieczne do przechowywania i nie wygasają niezależnie. Utracony token oznacza utratę kontroli nad tym zasobem (plik/zestaw/przesyłka) — traktuj je jak lokalne hasła.
Authorization: Owner <token>
# lub razem z sesją Bearer
X-Owner-Token: <token>
Token gościa
Anonimowi klienci potrzebują sposobu, by udowodnić, że to ich przesyłki, bez konta. Używamy visitor token — losowego ciągu znaków, który klient generuje raz i potem ponownie wykorzystuje. Wyślij go w każdej prośbie: W wersji web token jest automatycznie zapisywany w ciasteczku visitor_token. CLI zapisuje go w ~/.config/storageto/token (zobacz Dokumentacja CLI).
X-Visitor-Token: <random-string>

Dla endpointów modyfikacji (delete, set password, change expiry) własność jest potwierdzana, jeśli albo token odwiedzającego pasuje do lub żądanie pochodzi z tego samego adresu IP, który utworzył plik. Oba mogą zostać utracone (wyczyszczone ciasteczka, zmiany sieci). W przyszłości preferowanym dowodem jest token właściciela.

Błędy

Błędy mają spójny format: { "success": false, "error": "…" }

200OK.
201Utworzono.
400Nieprawidłowe żądanie (np. przekroczono limit rozmiaru kolekcji).
401Wymagane hasło lub hasło jest nieprawidłowe.
403Brak uprawnień (nie jesteś właścicielem zasobu).
404Nie znaleziono zasobu lub wygasł.
422Walidacja nie powiodła się lub obowiązuje ograniczenie planu/limitu.
429Przekroczono limit szybkości lub limit uploadu.
500Błąd serwera. Sprawdź status.

Limity zapytań

Wszystkie limity szybkości są liczone na podstawie IP. Odpowiedź 429 zawiera standardowe nagłówki Retry-After, X-RateLimit-Limit i X-RateLimit-Remaining.

Inicjowanie / potwierdzanie / anulowanie uploadu60 / minuta
Zakończenie multipart500 / minuta
Adresy URL części multipart120 / minuta
Inicjowanie / potwierdzanie wsadowe500 / minuta
Pobieranie statusu (plik i kolekcja)120 / minuta
Ustawienia (hasło, wygaśnięcie, maks. liczba pobrań)30 / minuta
Weryfikacja hasła10 / minuta
Tworzenie kolekcji30 / minuta
Zarządzanie (ready, delete)60 / minuta
Upload miniatury120 / minuta
Upload ShareX20 / dzień
Analityka aplikacji / błędy120 i 60 / minuta

Limit uploadu: anonimowi klienci mają dwa równoległe limity - 100 GB / 24 h na visitor token i 500 GB / 24 h na IP (limit IP łapie ruch bez tokena i w sieciach współdzielonych). Gdy którykolwiek zostanie przekroczony, dostaniesz 429 z szczegółami. To jest limit wyłącznie na upload - pobieranie jest nieograniczone i bez ograniczeń.

Upload

8 endpointów

Trzystopniowy proces uploadu dla każdego pliku, w tym plików większych niż 5 GB (automatycznie multipart). Jeśli potrzebujesz tylko szybkiego uploadu w stylu zrzutu ekranu, zamiast tego zobacz ShareX.

POST/upload/init60/min

Rozpocznij upload. Dla plików >50 MB odpowiedź to upload multipart (pole type: "multipart"); w przeciwnym razie pojedynczy presigned PUT.

Treść żądania

PoleTypOpis
filenamestring · requiredOryginalna nazwa pliku. Maks. 255 znaków.
content_typestring · requiredTyp MIME.
sizeinteger · requiredRozmiar pliku w bajtach. Min. 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/partsTylko właściciel120/min

Zażądaj dodatkowych adresów URL części dla trwającego przesyłania multipart. Używane, gdy /init zwróciło mniej adresów URL niż masz części (albo wygasły).

Treść żądania

PoleTypOpis
upload_idstring · requiredIdentyfikator upload_id z /init.
part_numbersarray<int> · requiredNumery części, dla których pobrać adresy 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-multipartTylko właściciel500/min

Zakończ przesyłanie multipart, gdy wszystkie części zostaną przesłane.

Treść żądania

PoleTypOpis
upload_idstring · requiredIdentyfikator upload_id z /init.
partsarray · requiredKażdy wpis: { partNumber, etag } z odpowiedzi na przesłanie części.
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/abortTylko właściciel60/min

Anuluj przesyłanie multipart i posprzątaj wszelkie częściowe dane.

Treść żądania

PoleTypOpis
upload_idstring · requiredPrzesyłanie do przerwania.
Request
curl -X POST https://storage.to/api/upload/abort \
  -H "Content-Type: application/json" \
  -d '{ "upload_id": "01HXYZ..." }'
POST/upload/confirm60/min

Potwierdź, że przesyłanie jest ukończone. W tym momencie tworzymy rekord File i zwracamy udostępniany adres URL.

Treść żądania

PoleTypOpis
filenamestring · requiredOryginalna nazwa pliku.
sizeinteger · requiredRozmiar pliku w bajtach.
content_typestring · requiredTyp MIME.
r2_keystring · requiredIdentyfikator r2_key z /init.
collection_idstring · optionalDodaj do kolekcji.
crc32integer · optionalSuma kontrolna CRC32 do weryfikacji integralności.
file_idstring(9) · optionalZrealizuj wcześniej utworzony identyfikator pliku zarezerwowane.
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

Zarezerwuj identyfikator pliku i udostępniany adres URL przed, gdy bajty będą gotowe. Przydatne, gdy musisz najpierw udostępnić link, a dopiero potem dokończyć przesyłanie. Własność jest powiązana z tokenem odwiedzającego + IP. Dokończ przesyłanie później za pomocą /upload/init + /upload/confirm, przekazując file_id do potwierdzenia.

Treść żądania

PoleTypOpis
filenamestring · optionalNazwa pliku zastępcza. Domyślnie "Pending".
content_typestring · optionalZastępczy typ MIME.
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_..."
}

Odpowiednik wsadowy /upload/init, zoptymalizowany pod przeglądarkowy uploader. Inicjuje do 250 plików w jednej rundzie żądań.

Używane wewnętrznie przez przeglądarkowy uploader. Większość klientów powinna preferować pojedynczy /upload/init dla pliku.

Odpowiednik wsadowy /upload/confirm. Potwierdza wiele plików w jednej rundzie żądań.

Kolekcje

9 endpointów

Kolekcja grupuje wiele plików pod jednym udostępnianym adresem URL (/c/{id}). Do 10 000 plików i łącznie 25 GB.

POST/collection30/min

Utwórz nową kolekcję. Dodaj pliki później, przekazując collection_id na /upload/confirm.

Treść żądania

PoleTypOpis
expected_file_countinteger · optionalWskazówka do automatycznego oznaczania kolekcji jako gotowej, gdy wszystkie oczekiwane pliki zostaną potwierdzone.
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_..."
}

Sprawdzaj stan kolekcji. Dodatkowo automatycznie oznacza kolekcję jako gotową, jeśli wszystkie oczekiwane pliki zostały potwierdzone.

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}/readyTylko właściciel60/min

Oznacz zestaw jako gotowy do pobrania. Zwykle nie jest to potrzebne — zestawy same stają się gotowe, gdy osiągną expected_file_count.

DELETE/collection/{id}Tylko właściciel60/min

Usuń kolekcję i wszystkie jej pliki.

POST/collection/{id}/passwordTylko właściciel30/min

Ustaw hasło dla kolekcji. Wymaga 4–100 znaków.

Treść żądania

PoleTypOpis
passwordstring · required4–100 znaków.
Request
curl -X POST https://storage.to/api/collection/ABC123xyz/password \
  -H "X-Visitor-Token: abc123" \
  -d '{ "password": "hunter22" }'
DELETE/collection/{id}/passwordTylko właściciel30/min

Usuń hasło z kolekcji.

Sprawdź hasło. Zwraca 200 w razie powodzenia, 401 w przypadku niepoprawnego hasła.

Treść żądania

PoleTypOpis
passwordstring · required
POST/collection/{id}/expiryTylko właścicielNa stałe: płatne30/min

Zmień datę ważności kolekcji.

Treść żądania

PoleTypOpis
daysinteger · optionalZa 1–7 dni, ale nie później niż 7 dni od przesłania (lub obecna data wygaśnięcia, jeśli jest późniejsza). Pomiń lub null, aby plik był stały (tylko premium).
POST/collection/{id}/max-downloadsTylko właściciel30/min

Ustaw limit pobrań (burn-after-N-downloads). Kolekcja usuwa się automatycznie po osiągnięciu limitu.

Treść żądania

PoleTypOpis
max_downloadsinteger · optional1–1000. Musi przekraczać bieżącą liczbę pobrań. null, aby usunąć limit.

Pliki

8 endpointów

Wszystkie ustawienia na poziomie pliku (hasło, wygaśnięcie, max-downloads) odzwierciedlają endpointy kolekcji. Tylko właściciel.

Sprawdź, czy plik nadal oczekuje na przesłanie.

Response
{ "pending": false }
DELETE/file/{id}Tylko właściciel60/min

Natychmiast usuń plik.

POST/file/{id}/thumbnailTylko właściciel120/min

Prześlij miniaturę dla pliku wideo lub obrazu (używane na stronie pobierania). Maks. 2 MB.

Treść żądania

PoleTypOpis
thumbnailimage · requiredPrzesyłanie multipart. Maks. 2 MB.
Response
{
  "success": true,
  "thumbnail_url": "https://..."
}
POST/file/{id}/passwordTylko właściciel30/min

Ustaw hasło dla pliku. Wymaga 4–100 znaków.

DELETE/file/{id}/passwordTylko właściciel30/min

Usuń hasło pliku.

Zweryfikuj hasło pliku.

POST/file/{id}/expiryTylko właścicielNa stałe: płatne30/min

Zmień datę ważności pliku.

Treść żądania

PoleTypOpis
daysinteger · optionalZa 1–7 dni, ale nie później niż 7 dni od przesłania (lub obecna data wygaśnięcia, jeśli jest późniejsza). Pomiń lub null, aby plik był stały (tylko premium).
POST/file/{id}/max-downloadsTylko właściciel30/min

Ogranicz łączną liczbę pobrań pliku. Usuwa się automatycznie po osiągnięciu limitu.

Upload ShareX

1 endpoint

Jednorazowy endpoint do przesyłania — wyślij plik multipart, a w odpowiedzi dostaniesz URL do udostępniania. Bez kombinacji init/confirm. Idealne dla narzędzi do zrzutów ekranu. Pełna instrukcja konfiguracji na /docs/sharex.

POST/sharex/upload20/day

Prześlij obraz lub plik bezpośrednio (formularz multipart, pole file). Maks. 25 MB.

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

Uwierzytelnianie na komputerze

2 endpointy

Dla zalogowanych klientów, takich jak aplikacja desktopowa, którzy mają token Bearer.

GET/userToken Bearer

Zwróć uwierzytelnionego użytkownika.

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/logoutToken Bearer

Unieważnij bieżący token dostępu.

Różne

5 endpointów

Stan, limity i telemetria klientów.

Sprawdzenie dostępności. Zwraca 200 z { "status": "ok" }, gdy worker API działa.

Response
{ "status": "ok" }

Na żywo: strumień aktywności dla globu na stronie głównej. Buforowane na krawędzi.

Aktualne wykorzystanie limitu przesyłania dla wywołującego — używane przez CLI i aplikację desktopową, by pokazać pozostałą pojemność. Format odpowiedzi różni się dla użytkowników uwierzytelnionych. Mimo nazwy URL śledzi to tylko bajty upload; pobrania nie są liczone.

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

Wyślij zdarzenie użycia z poziomu CLI lub aplikacji desktopowej.

Treść żądania

PoleTypOpis
appstring · requireddesktop, cli lub web.
versionstring · optionalWersja klienta.
eventstring · requiredNazwa zdarzenia, np. upload_complete.
contextobject · optionalDodatkowe metadane.
POST/app-errors60/min

Wyślij raport błędu z CLI lub aplikacji desktopowej. Dedupikacja po stronie serwera — maks. 10 takich samych błędów na godzinę.

Treść żądania

PoleTypOpis
appstring · requireddesktop, cli lub web.
typestring · requiredKlasa/typ błędu.
messagestring · requiredKomunikat błędu.
stackstring · optionalŚlad stosu (stack trace).
version, os, os_version, arch, contextvarious · optionalMetadane diagnostyczne.