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:
- Inizializza — ci dici che vuoi caricare un file. Ti restituiamo uno o più URL presignati che puntano a Cloudflare R2.
- Carica su R2 — :inserisci i tuoi byte direttamente nell’URL(i) presigned. I byte non passano dai nostri server.
- Conferma — ci dici che il caricamento è terminato. Creiamo un record
Filee 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
Usiamo token bearer Laravel Sanctum. Genera un token tramite il passaggio OAuth del desktop o l’accesso web, poi invialo come:
Authorization: Bearer <token>
Token visitatore
I client anonimi hanno bisogno di un modo per dimostrare la proprietà dei propri caricamenti senza un account. Usiamo un 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 dell’owner come prova valida di proprietà insieme al fallback legacy visitor token + IP — i client che hanno il token continuano a funzionare anche dopo aver cambiato rete o cancellato i cookie, mentre i client che non lo hanno funzionano esattamente come prima.
I token restano validi finché esiste la risorsa, sono sicuri da conservare e non scadono in modo indipendente. Un token perso 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:
| Codice | Significato |
|---|---|
200 | OK. |
201 | Creato. |
400 | Richiesta non valida (es. limite di dimensione della collezione superato). |
401 | Password richiesta o non corretta. |
403 | Non autorizzato (non sei il proprietario della risorsa). |
404 | Risorsa non trovata o scaduta. |
422 | Validazione non riuscita, oppure restrizione di piano/quota. |
429 | Limite di rate o quota di upload superata. |
500 | Errore 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.
| Ambito | Limite |
|---|---|
| Avvio / conferma / annullamento upload | 60 / minuto |
| Completamento multipart | 500 / minuto |
| URL delle parti multipart | 120 / minuto |
| Avvio / conferma batch | 500 / minuto |
| Verifiche dello stato (file e collezione) | 120 / minuto |
| Impostazioni (password, scadenza, max-download) | 30 / minuto |
| Verifica password | 10 / minuto |
| Creazione collezione | 30 / minuto |
| Gestione (pronto, elimina) | 60 / minuto |
| Caricamento thumbnail | 120 / minuto |
| Upload con ShareX | 20 / giorno |
| Analytics dell’app / errori | 120 e 60 / minuto |
Quota di upload: i client anonimi hanno due limiti che girano 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. È una quota solo 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.
/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
| Campo | Tipo | Descrizione |
|---|---|---|
filename | string · required | Nome file originale. Max 255 caratteri. |
content_type | string · required | Tipo MIME. |
size | integer · required | Dimensione del file in byte. Min 1. |
/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
| Campo | Tipo | Descrizione |
|---|---|---|
upload_id | string · required | L'upload_id da /init. |
part_numbers | array<int> · required | Numeri delle parti per cui ottenere gli URL. |
/upload/complete-multipart
Owner only
500/min
Completa un upload multipart su R2 una volta caricate tutte le parti.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
upload_id | string · required | L'upload_id da /init. |
parts | array · required | Ogni voce: { partNumber, etag } dalla risposta di R2. |
/upload/abort
Owner only
60/min
Annulla un upload multipart e ripulisci eventuali dati parziali su R2.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
upload_id | string · required | L'upload da annullare. |
/upload/confirm
60/min
Conferma che l'upload è completato. È qui che creiamo il record File e restituiamo l'URL condivisibile.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
filename | string · required | Nome file originale. |
size | integer · required | Dimensione del file in byte. |
content_type | string · required | Tipo MIME. |
r2_key | string · required | L'r2_key da /init. |
collection_id | string · optional | Aggiungi a una raccolta. |
crc32 | integer · optional | Checksum CRC32 per la verifica dell'integrità. |
file_id | string(9) · optional | Completa un ID file precedentemente riservato. |
/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
| Campo | Tipo | Descrizione |
|---|---|---|
filename | string · optional | Nome file segnaposto. Impostazione predefinita: "Pending". |
content_type | string · optional | Tipo MIME segnaposto. |
/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.
/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.
/collection
30/min
Crea una nuova raccolta. Aggiungi i file in seguito passando collection_id su /upload/confirm.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
expected_file_count | integer · optional | Suggerimento per contrassegnare automaticamente la raccolta come pronta una volta che tutti i file previsti sono stati confermati. |
/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.
/collection/{id}/ready
Owner only
60/min
Segna la raccolta come pronta per il download. Di solito non serve: le raccolte diventano automaticamente pronte quando viene raggiunto expected_file_count.
/collection/{id}
Owner only
60/min
Elimina una raccolta e tutti i suoi file.
/collection/{id}/password
Owner only
30/min
Imposta una password sulla raccolta. Richiede 4–100 caratteri.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
password | string · required | 4–100 caratteri. |
/collection/{id}/password
Owner only
30/min
Rimuovi la password da una raccolta.
/collection/{id}/verify-password
10/min
Verifica una password. Restituisce 200 in caso di successo, 401 se la password è errata.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
password | string · required |
/collection/{id}/expiry
Owner only
30/min
Cambia la scadenza di una raccolta.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
days | integer · optional | Da 1 a 7 giorni da oggi. Ommetti o null per la durata permanente (solo premium). |
/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
| Campo | Tipo | Descrizione |
|---|---|---|
max_downloads | integer · optional | 1–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.
/file/{id}/status
120/min
Controlla se un file è ancora in attesa del caricamento.
/file/{id}
Owner only
60/min
Elimina un file immediatamente.
/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
| Campo | Tipo | Descrizione |
|---|---|---|
thumbnail | image · required | Upload multipart. Max 2 MB. |
/file/{id}/password
Owner only
30/min
Imposta una password su un file. Richiede 4–100 caratteri.
/file/{id}/password
Owner only
30/min
Rimuovi la password di un file.
/file/{id}/verify-password
10/min
Verifica la password di un file.
/file/{id}/expiry
Owner only
30/min
Cambia la scadenza di un file.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
days | integer · optional | Da 1 a 7 giorni da oggi. Ommetti o null per la durata permanente (solo premium). |
/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 indietro un URL condivisibile. Niente passaggi init/confirm. Ideale per strumenti di screenshot. Guida completa alla configurazione su /it/docs/sharex.
Autenticazione desktop
Per client autenticati (ad es. l'app desktop) che hanno un token Sanctum.
/user
Bearer token
Restituisci l’utente autenticato.
/auth/logout
Bearer token
Revoca il token di accesso corrente.
Varie
/health
Controllo di salute. Fa ping al database, allo storage R2 e alla cache Redis. Restituisce 200 se tutto è verde, 503 in caso contrario.
/activity
Flusso live delle attività per il globo della home. Memorizzato nella cache ai margini di Cloudflare.
/bandwidth/status
60/min
Utilizzo attuale della quota di upload per il chiamante — usato da CLI e app desktop per mostrare la capacità residua. La struttura della risposta cambia per gli utenti autenticati. Nonostante il nome dell’URL, tiene traccia solo di upload byte; i download non vengono conteggiati.
/app-analytics
120/min
Invia un evento di utilizzo dalla CLI o dall’app desktop.
Corpo della richiesta
| Campo | Tipo | Descrizione |
|---|---|---|
app | string · required | desktop, cli o web. |
version | string · optional | Versione del client. |
event | string · required | Nome dell’evento, ad es. upload_complete. |
context | object · optional | Metadati extra. |
/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
| Campo | Tipo | Descrizione |
|---|---|---|
app | string · required | desktop, cli o web. |
type | string · required | Classe/tipo di errore. |
message | string · required | Messaggio di errore. |
stack | string · optional | Stack trace. |
version, os, os_version, arch, context | various · optional | Metadati diagnostici. |