REST API

Carica file, crea collezioni e gestisci le condivisioni via HTTP. Tutte le risposte sono in formato JSON; per i caricamenti anonimi non è richiesta alcuna chiave API.

Introduzione

La API di storage.to alimenta CLI, app desktop, caricatore web e qualsiasi client di terze parti che vuoi creare.

Il flusso di caricamento è in tre passaggi:

  1. Inizializza - ci dici che vuoi caricare un file. Ti restituiamo uno o più URL presignati che puntano a Cloudflare R2.
  2. Carica su R2 - :inserisci i tuoi byte direttamente nell’URL(i) presigned. I byte non passano dai nostri server.
  3. Conferma - ci dici che il caricamento è terminato. Creiamo un record File e ti forniamo un URL condivisibile.

URL di base

https://storage.to/api

Tutti gli endpoint qui sotto sono relativi a questa base. Esempio: POST /upload/init significa POST https://storage.to/api/upload/init.

Autenticazione

La maggior parte degli endpoint non richiede autenticazione. I caricamenti anonimi sono una funzionalità fondamentale.

L’autenticazione è facoltativa e sblocca:

  • Caricamenti associati al tuo account (visibili su /dashboard)
  • Funzionalità premium (file permanenti, spazio maggiore)
  • Modifiche basate sulla proprietà (elimina, imposta password, cambia scadenza) senza dover corrispondere al visitor-token

Per autenticarti, genera un token API personale dal tuo account e invialo come bearer token su ogni richiesta:

Authorization: Bearer <token>

Genera token API

Devi aver effettuato l’accesso. Il token completo viene mostrato solo una volta al momento della creazione, quindi copialo in un posto sicuro. Puoi revocare un token in qualsiasi momento dalla stessa pagina.

Token visitatore

I client anonimi hanno bisogno di un modo per dimostrare la proprietà dei propri upload senza un account. Usiamo una visitor token: una stringa casuale che il client genera una volta e riutilizza. Inviatela con ogni richiesta:

X-Visitor-Token: <random-string>

Sul web, il token viene salvato automaticamente nel cookie visitor_token. La CLI lo salva in ~/.config/storageto/token (vedi Documentazione CLI).

Per gli endpoint di mutazione (elimina, imposta password, cambia scadenza), la proprietà è confermata se oppure il token del visitatore corrisponde o la richiesta proviene dallo stesso IP che ha creato il file. Entrambi possono andare persi (cookie cancellati, cambi di rete). Da ora in poi, la prova preferita è token dell’owner.

Token proprietario

Ogni endpoint che crea risorse (/upload/init multipart, /upload/confirm, /upload/reserve, /collection) restituisce un owner_token nella risposta. Il token è una prova firmata di proprietà legata a quella specifica risorsa, indipendente dal tuo IP o dal token del visitatore.

Salva il token insieme all’ID della risorsa e invialo in qualsiasi mutazione come:

Authorization: Owner <token>

Oppure, se stai già usando Authorization: Bearer per una sessione autenticata, invialo come:

X-Owner-Token: <token>

Il server accetta il token del proprietario come prova valida di proprietà insieme al vecchio fallback visitor token + IP: i client che hanno il token continuano a funzionare anche dopo aver cambiato rete o cancellato i cookie, mentre quelli che non ce l’hanno funzionano esattamente come prima.

I token durano quanto dura la risorsa, sono sicuri da mantenere e non scadono in modo indipendente. Un token smarrito significa perdere il controllo di quella risorsa (file/collezione/upload): trattali come password locali.

Errori

Gli errori seguono una struttura coerente:

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

Codici di stato HTTP comuni:

CodiceSignificato
200OK.
201Creato.
400Richiesta non valida (es. limite di dimensione della collezione superato).
401Password richiesta o non corretta.
403Non autorizzato (non sei il proprietario della risorsa).
404Risorsa non trovata o scaduta.
422Validazione non riuscita, oppure restrizione di piano/quota.
429Limite di rate o quota di upload superata.
500Errore del server. Controlla stato.

Limiti di velocità

Tutti i limiti di rate sono per IP. Una risposta 429 include gli header standard Retry-After, X-RateLimit-Limit e X-RateLimit-Remaining.

AmbitoLimite
Avvio / conferma / annullamento upload60 / minuto
Completamento multipart500 / minuto
URL delle parti multipart120 / minuto
Avvio / conferma batch500 / minuto
Verifiche dello stato (file e collezione)120 / minuto
Impostazioni (password, scadenza, max-download)30 / minuto
Verifica password10 / minuto
Creazione collezione30 / minuto
Gestione (pronto, elimina)60 / minuto
Caricamento thumbnail120 / minuto
Upload con ShareX20 / giorno
Analytics dell’app / errori120 e 60 / minuto

Quota di upload: I client anonimi hanno due limiti in parallelo: 100 GB / 24 h per visitor token e 500 GB / 24 h per IP (il limite IP intercetta il traffico senza token e le reti condivise). Quando uno dei due viene superato riceverai un 429 con i dettagli. È solo una quota upload: i download sono illimitati e senza limitazioni (serviti direttamente da URL firmati R2).

Carica

Il flusso di upload in tre passaggi per qualsiasi file, inclusi quelli oltre 5 GB (multipart in automatico). Se ti serve solo un upload rapido in stile screenshot, guarda invece ShareX.

POST /upload/init 60/min

Avvia un upload. Per i file >50 MB la risposta è un upload multipart (campo type: "multipart"); altrimenti un singolo PUT presigned.

Corpo della richiesta

CampoTipoDescrizione
filenamestring · requiredNome file originale. Max 255 caratteri.
content_typestring · requiredTipo MIME.
sizeinteger · requiredDimensione del file in byte. 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/parts Owner only 120/min

Richiedi URL aggiuntivi per le parti di un upload multipart in corso. Usato quando /init ha restituito meno URL di quante parti hai (oppure sono scaduti).

Corpo della richiesta

CampoTipoDescrizione
upload_idstring · requiredL'upload_id da /init.
part_numbersarray<int> · requiredNumeri delle parti per cui ottenere gli 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

Completa un upload multipart su R2 una volta caricate tutte le parti.

Corpo della richiesta

CampoTipoDescrizione
upload_idstring · requiredL'upload_id da /init.
partsarray · requiredOgni voce: { partNumber, etag } dalla risposta di 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

Annulla un upload multipart e ripulisci eventuali dati parziali su R2.

Corpo della richiesta

CampoTipoDescrizione
upload_idstring · requiredL'upload da annullare.
Request
curl -X POST https://storage.to/api/upload/abort \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ..." }'
POST /upload/confirm 60/min

Conferma che l'upload è completato. È qui che creiamo il record File e restituiamo l'URL condivisibile.

Corpo della richiesta

CampoTipoDescrizione
filenamestring · requiredNome file originale.
sizeinteger · requiredDimensione del file in byte.
content_typestring · requiredTipo MIME.
r2_keystring · requiredL'r2_key da /init.
collection_idstring · optionalAggiungi a una raccolta.
crc32integer · optionalChecksum CRC32 per la verifica dell'integrità.
file_idstring(9) · optionalCompleta un ID file precedentemente riservato.
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

Riserva un ID file e un URL condivisibile prima che i byte siano pronti. Utile quando devi consegnare prima un link e completare l'upload dopo. La proprietà è legata al tuo token visitatore + IP. Completa l'upload più tardi con /upload/init + /upload/confirm, passando file_id per la conferma.

Corpo della richiesta

CampoTipoDescrizione
filenamestring · optionalNome file segnaposto. Impostazione predefinita: "Pending".
content_typestring · optionalTipo MIME segnaposto.
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

Equivalente batch di /upload/init, ottimizzato per l'uploader web. Avvia fino a 250 file in un solo round-trip.

Usato internamente dall'uploader web. La maggior parte dei client dovrebbe preferire /upload/init per singolo file.

POST /upload/confirm-batch 500/min

Equivalente batch di /upload/confirm. Conferma molti file in un solo round-trip.

Raccolte

Una raccolta raggruppa più file sotto un unico URL di condivisione (/c/{id}). Fino a 10.000 file e 25 GB totali.

POST /collection 30/min

Crea una nuova raccolta. Aggiungi i file in seguito passando collection_id su /upload/confirm.

Corpo della richiesta

CampoTipoDescrizione
expected_file_countinteger · optionalSuggerimento per contrassegnare automaticamente la raccolta come pronta una volta che tutti i file previsti sono stati confermati.
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

Controlla lo stato di una raccolta. Contrassegna automaticamente la raccolta come pronta anche se tutti i file previsti sono stati confermati.

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

Segna la collezione come pronta per il download. Di solito non serve: le collezioni diventano automaticamente pronte quando si raggiunge expected_file_count.

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

Elimina una raccolta e tutti i suoi file.

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

Imposta una password sulla raccolta. Richiede 4–100 caratteri.

Corpo della richiesta

CampoTipoDescrizione
passwordstring · required4–100 caratteri.
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

Rimuovi la password da una raccolta.

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

Verifica una password. Restituisce 200 in caso di successo, 401 se la password è errata.

Corpo della richiesta

CampoTipoDescrizione
passwordstring · required
POST /collection/{id}/expiry Owner only 30/min

Cambia la scadenza di una raccolta.

Corpo della richiesta

CampoTipoDescrizione
daysinteger · optionalDa 1 a 7 giorni da oggi. Ommetti o null per la durata permanente (solo premium).
POST /collection/{id}/max-downloads Owner only 30/min

Imposta un limite di download (burn-after-N-downloads). La raccolta viene eliminata automaticamente quando viene raggiunto il limite.

Corpo della richiesta

CampoTipoDescrizione
max_downloadsinteger · optional1–1000. Deve superare il numero di download attuale. null per rimuovere il limite.

File

Tutte le impostazioni a livello file (password, scadenza, max-downloads) rispecchiano gli endpoint della raccolta. Solo il proprietario.

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

Controlla se un file è ancora in attesa del caricamento.

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

Elimina un file immediatamente.

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

Carica un'immagine thumbnail per un file video o immagine (usata nella pagina di download). Max 2 MB.

Corpo della richiesta

CampoTipoDescrizione
thumbnailimage · requiredUpload multipart. Max 2 MB.
Response
{ "success": true, "thumbnail_url": "https://..." }
POST /file/{id}/password Owner only 30/min

Imposta una password su un file. Richiede 4–100 caratteri.

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

Rimuovi la password di un file.

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

Verifica la password di un file.

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

Cambia la scadenza di un file.

Corpo della richiesta

CampoTipoDescrizione
daysinteger · optionalDa 1 a 7 giorni da oggi. Ommetti o null per la durata permanente (solo premium).
POST /file/{id}/max-downloads Owner only 30/min

Limita il numero totale di download di un file. Si elimina automaticamente quando viene raggiunto il limite.

Upload con ShareX

Endpoint di upload one-shot: invia un file multipart e ricevi un URL condivisibile. Niente passaggi di init/conferma. Ideale per strumenti di screenshot. Guida completa alla configurazione su /it/docs/sharex.

POST /sharex/upload 20/day

Carica direttamente un'immagine o un file (form multipart, campo file). Max 25 MB.

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

Autenticazione desktop

Per client autenticati (ad es. l'app desktop) che hanno un token Sanctum.

GET /user Bearer token

Restituisci l’utente autenticato.

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

Revoca il token di accesso corrente.

Varie

GET /health

Controllo di salute. Fa ping al database, allo storage R2 e alla cache Redis. Restituisce 200 se tutto è verde, 503 in caso contrario.

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

Flusso live delle attività per il globo della home. Memorizzato nella cache ai margini di Cloudflare.

GET /bandwidth/status 60/min

Utilizzo attuale della quota di upload per il chiamante: usato dalla CLI e dall’app desktop per mostrare la capacità residua. La struttura della risposta cambia per gli utenti autenticati. Nonostante il nome dell’URL, tiene traccia solo dei byte upload; i download non vengono conteggiati.

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

Invia un evento di utilizzo dalla CLI o dall’app desktop.

Corpo della richiesta

CampoTipoDescrizione
appstring · requireddesktop, cli o web.
versionstring · optionalVersione del client.
eventstring · requiredNome dell’evento, ad es. upload_complete.
contextobject · optionalMetadati extra.
POST /app-errors 60/min

Invia una segnalazione di errore dalla CLI o dall’app desktop. Deduplicata lato server: massimo 10 dello stesso errore per ora.

Corpo della richiesta

CampoTipoDescrizione
appstring · requireddesktop, cli o web.
typestring · requiredClasse/tipo di errore.
messagestring · requiredMessaggio di errore.
stackstring · optionalStack trace.
version, os, os_version, arch, contextvarious · optionalMetadati diagnostici.
Caricamenti recenti
Nessun caricamento recente.

This list only lives on this browser.

Create a free account to find your files anywhere →