REST API
Lade Dateien hoch, erstelle Sammlungen und verwalte Freigaben über HTTP. Alle Antworten sind JSON; kein API-Schlüssel für anonyme Uploads erforderlich.
Einführung
Die storage.to API treibt unser CLI, Desktop-App, Web-Uploader und jeden Drittanbieter-Client an, den du bauen möchtest.
Der Upload-Ablauf besteht aus drei Schritten:
- Initialisieren — Sag uns, dass du eine Datei hochladen möchtest. Wir geben eine oder mehrere vorgezeichnete URLs zurück, die auf Cloudflare R2 zeigen.
- Upload zu R2 —
PUTdeine Bytes direkt an die vorab signierte(n) URL(s). Die Bytes laufen nicht über unsere Server. - Bestätigen — Sag uns, dass der Upload abgeschlossen ist. Wir erstellen einen
FileEintrag und geben dir eine teilbare URL.
Basis-URL
https://storage.to/api
Alle untenstehenden Endpunkte sind relativ zu dieser Basis. Beispiel: POST /upload/init bedeutet POST https://storage.to/api/upload/init.
Authentifizierung
Die meisten Endpunkte erfordern keine Authentifizierung. Anonyme Uploads sind eine Kernfunktion.
Authentifizierung ist optional und schaltet Folgendes frei:
- Uploads, die deinem Konto zugeordnet sind (sichtbar unter /dashboard)
- Premium-Funktionen (permanente Dateien, größerer Speicher)
- Besitzbasierte Änderungen (Löschen, Passwort setzen, Ablauf ändern) ohne Übereinstimmung des Besucher-Tokens
Wir verwenden Laravel Sanctum Bearer-Tokens. Erstelle ein Token über die Desktop-OAuth-Übergabe oder das Web-Login und sende es dann als:
Authorization: Bearer <token>
Besucher-Token
Anonyme Clients benötigen eine Möglichkeit, den Besitz ihrer eigenen Uploads ohne Konto nachzuweisen. Wir verwenden ein Besucher-Token — eine zufällige Zeichenfolge, die der Client einmal generiert und wiederverwendet. Sende es mit jeder Anfrage:
X-Visitor-Token: <random-string>
Im Web wird das Token automatisch im visitor_token Cookie gespeichert. Die CLI speichert es unter ~/.config/storageto/token (siehe CLI-Dokumentation).
Für Änderungs-Endpunkte (Löschen, Passwort setzen, Ablauf ändern) wird der Besitz bestätigt, wenn entweder das Besucher-Token übereinstimmt oder die Anfrage von derselben IP kommt, die die Datei erstellt hat.
Fehler
Fehler folgen einer einheitlichen Struktur:
{
"success": false,
"error": "Human-readable message"
}
Übliche HTTP-Statuscodes:
| Code | Bedeutung |
|---|---|
200 | OK. |
201 | Erstellt. |
400 | Fehlerhafte Anfrage (z. B. Sammlungslimit überschritten). |
401 | Passwort erforderlich oder falsch. |
403 | Nicht autorisiert (nicht der Besitzer der Ressource). |
404 | Ressource nicht gefunden oder abgelaufen. |
422 | Validierung fehlgeschlagen oder Plan-/Kontingentbeschränkung. |
429 | Rate-Limit oder Upload-Kontingent erreicht. |
500 | Serverfehler. Prüfe Status. |
Ratenbegrenzungen
Alle Ratenbegrenzungen gelten pro IP. Eine 429-Antwort enthält die Standard-Header Retry-After, X-RateLimit-Limit und X-RateLimit-Remaining.
| Bereich | Limit |
|---|---|
| Upload starten / bestätigen / abbrechen | 60 / Minute |
| Multipart-Abschluss | 500 / Minute |
| Multipart-Teil-URLs | 120 / Minute |
| Batch starten / bestätigen | 500 / Minute |
| Statusabfragen (Datei & Sammlung) | 120 / Minute |
| Einstellungen (Passwort, Ablauf, max. Downloads) | 30 / Minute |
| Passwortüberprüfung | 10 / Minute |
| Sammlung erstellen | 30 / Minute |
| Verwalten (bereit, löschen) | 60 / Minute |
| Thumbnail-Upload | 120 / Minute |
| ShareX-Upload | 20 / Tag |
| App-Analysen / Fehler | 120 und 60 / Minute |
Upload-Kontingent: Anonyme Clients haben zwei parallele Limits – 100 GB / 24 Std. pro Besucher-Token und 500 GB / 24 Std. pro IP (das IP-Limit erfasst tokenlosen Traffic und geteilte Netzwerke). Wird eines überschritten, erhältst du einen 429 mit Details. Dies ist nur ein Upload Kontingent – Downloads sind unbegrenzt und ungedrosselt (werden direkt von R2 signierten URLs ausgeliefert).
Hochladen
Der dreistufige Upload-Prozess für jede Datei, auch über 5 GB (automatisch multipart). Für einen schnellen Screenshot-Upload siehe stattdessen ShareX.
/upload/init
60/min
Starte einen Upload. Bei Dateien >50 MB enthält die Antwort part_urls für einen Multipart-Upload; ansonsten eine einzelne url.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
filename | string · required | Originaldateiname. Maximal 255 Zeichen. |
content_type | string · required | MIME-Typ. |
size | integer · required | Dateigröße in Bytes. Mindestens 1. |
/upload/parts
120/min
Fordere zusätzliche Teil-URLs für einen laufenden Multipart-Upload an. Wird verwendet, wenn /init weniger URLs zurückgab als Teile vorhanden sind (oder diese abgelaufen sind).
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
upload_id | string · required | Die upload_id von /init. |
part_numbers | array<int> · required | Teilnummern, für die URLs angefordert werden. |
/upload/complete-multipart
500/min
Schließe einen Multipart-Upload auf R2 ab, sobald alle Teile hochgeladen sind.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
upload_id | string · required | Die upload_id von /init. |
parts | array · required | Jeder Eintrag: { partNumber, etag } aus der R2-Antwort. |
/upload/abort
60/min
Brich einen Multipart-Upload ab und bereinige alle Teil-Daten auf R2.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
upload_id | string · required | Der Upload, der abgebrochen werden soll. |
/upload/confirm
60/min
Bestätige, dass der Upload abgeschlossen ist. Hier erstellen wir den File-Eintrag und geben die teilbare URL zurück.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
filename | string · required | Originaldateiname. |
size | integer · required | Dateigröße in Bytes. |
content_type | string · required | MIME-Typ. |
r2_key | string · required | Die r2_key von /init. |
collection_id | string · optional | An eine Sammlung anhängen. |
crc32 | integer · optional | CRC32-Prüfsumme zur Integritätsprüfung. |
file_id | string(9) · optional | Erfülle eine zuvor reserviert Datei-ID. |
/file/reserve
60/min
Reserviere eine Datei-ID und teilbare URL bevor die Bytes bereit sind. Nützlich, wenn du zuerst einen Link ausgeben und den Upload später abschließen möchtest. Die Eigentümerschaft ist an deinen Besuchertoken + IP gebunden. Beende den Upload später mit /upload/init + /upload/confirm, wobei file_id zur Bestätigung übergeben wird.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
filename | string · optional | Platzhalter-Dateiname. Standard ist "Pending". |
content_type | string · optional | Platzhalter-MIME-Typ. |
/upload/init-batch
500/min
Batch-Äquivalent zu /upload/init, optimiert für den Web-Uploader. Initiiert bis zu 250 Dateien in einer einzigen Runde.
Wird intern vom Web-Uploader verwendet. Die meisten Clients sollten das Single-File-/upload/init bevorzugen.
/upload/confirm-batch
500/min
Batch-Äquivalent zu /upload/confirm. Bestätigt viele Dateien in einer einzigen Runde.
Sammlungen
Eine Sammlung fasst mehrere Dateien unter einer einzigen Freigabe-URL (/c/{id}) zusammen. Bis zu 10.000 Dateien und insgesamt 25 GB.
/collection
30/min
Erstelle eine neue Sammlung. Füge danach Dateien hinzu, indem du collection_id an /upload/confirm übergibst.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
expected_file_count | integer · optional | Hinweis zum automatischen Markieren der Sammlung als bereit, sobald alle erwarteten Dateien bestätigt wurden. |
/collection/{id}/status
120/min
Abfrage des Status einer Sammlung. Markiert die Sammlung auch automatisch als bereit, wenn alle erwarteten Dateien bestätigt sind.
/collection/{id}/ready
Owner only
60/min
Markiere die Sammlung als bereit zum Download. Normalerweise nicht nötig – Sammlungen werden automatisch bereit, sobald expected_file_count erreicht ist.
/collection/{id}
Owner only
60/min
Lösche eine Sammlung und alle ihre Dateien.
/collection/{id}/password
Owner only
30/min
Setze ein Passwort für die Sammlung. Erfordert 4–100 Zeichen.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
password | string · required | 4–100 Zeichen. |
/collection/{id}/password
Owner only
30/min
Entferne das Passwort von einer Sammlung.
/collection/{id}/verify-password
10/min
Überprüfe ein Passwort. Gibt 200 bei Erfolg zurück, 401 bei falschem Passwort.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
password | string · required |
/collection/{id}/expiry
Owner only
30/min
Ändere das Ablaufdatum einer Sammlung.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
days | integer · optional | 1–7 Tage ab jetzt. Weglassen oder null für dauerhaft (nur Premium). |
/collection/{id}/max-downloads
Owner only
30/min
Setze ein Download-Limit (burn-after-N-downloads). Die Sammlung wird automatisch gelöscht, wenn das Limit erreicht ist.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
max_downloads | integer · optional | 1–1000. Muss die aktuelle Download-Anzahl übersteigen. null entfernt das Limit. |
Dateien
Alle dateibezogenen Einstellungen (Passwort, Ablauf, max. Downloads) spiegeln die Sammlung-Endpunkte wider. Nur für Besitzer.
/file/{id}/status
120/min
Prüfe, ob eine Datei noch auf den Upload wartet.
/file/{id}
Owner only
60/min
Lösche eine Datei sofort.
/file/{id}/thumbnail
Owner only
120/min
Lade ein Vorschaubild für eine Video- oder Bilddatei hoch (wird auf der Download-Seite verwendet). Max. 2 MB.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
thumbnail | image · required | Multipart-Upload. Max. 2 MB. |
/file/{id}/password
Owner only
30/min
Setze ein Passwort für eine Datei. Erfordert 4–100 Zeichen.
/file/{id}/password
Owner only
30/min
Entferne das Passwort einer Datei.
/file/{id}/verify-password
10/min
Überprüfe das Passwort einer Datei.
/file/{id}/expiry
Owner only
30/min
Ändere das Ablaufdatum einer Datei.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
days | integer · optional | 1–7 Tage ab jetzt. Weglassen oder null für dauerhaft (nur Premium). |
/file/{id}/max-downloads
Owner only
30/min
Begrenze die Gesamtzahl der Downloads einer Datei. Löscht die Datei automatisch, wenn erreicht.
ShareX-Upload
One-Shot-Upload-Endpunkt — sende eine Multipart-Datei und erhalte eine teilbare URL zurück. Kein Init-/Bestätigungsprozess. Ideal für Screenshot-Tools. Vollständige Anleitung unter /de/docs/sharex.
Desktop-Authentifizierung
Für authentifizierte Clients (z. B. die Desktop-App) mit einem Sanctum-Token.
/user
Bearer token
Gibt den authentifizierten Benutzer zurück.
/auth/logout
Bearer token
Widerrufe das aktuelle Zugriffstoken.
Verschiedenes
/health
Health-Check. Prüft Datenbank, R2-Speicher und Redis-Cache. Gibt 200 zurück, wenn alles in Ordnung ist, sonst 503.
/activity
Live-Aktivitätsstream für die Startseiten-Weltkugel. Im Cloudflare-Edge zwischengespeichert.
/bandwidth/status
60/min
Aktuelle Upload-Kontingentnutzung des Aufrufers – wird von CLI und Desktop-App genutzt, um die verbleibende Kapazität anzuzeigen. Antwortformat unterscheidet sich bei authentifizierten Nutzern. Trotz des URL-Namens werden nur Upload Bytes erfasst; Downloads werden nicht gezählt.
/app-analytics
120/min
Sende ein Nutzungsereignis von der CLI oder Desktop-App.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
app | string · required | desktop, cli oder web. |
version | string · optional | Client-Version. |
event | string · required | Ereignisname, z. B. upload_complete. |
context | object · optional | Zusätzliche Metadaten. |
/app-errors
60/min
Sende einen Fehlerbericht von der CLI oder Desktop-App. Serverseitig dedupliziert – max. 10 gleiche Fehler pro Stunde.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
app | string · required | desktop, cli oder web. |
type | string · required | Fehlerklasse/-typ. |
message | string · required | Fehlermeldung. |
stack | string · optional | Stack-Trace. |
version, os, os_version, arch, context | various · optional | Diagnostische Metadaten. |