REST-API
Dateien hochladen, Sammlungen erstellen und Freigaben per HTTP verwalten. Alle Antworten sind JSON; fĂĽr anonyme Uploads ist kein API-SchlĂĽssel erforderlich.
EinfĂĽhrung
Die storage.to-API treibt unsere CLI, Desktop-App, Web-Uploader und alle Drittanbieter-Clients, die du bauen möchtest.
Der Upload-Ablauf besteht aus drei Schritten:
- Initialisieren - Sag uns, dass du eine Datei hochladen möchtest. Wir geben dir eine oder mehrere vorab signierte URLs zurück, die auf Cloudflare R2 zeigen.
- In R2 hochladen -
PUTdeine Bytes direkt in die vorab signierten URL(s). Die Bytes laufen nicht über unsere Server. - Bestätigen - Sag uns, dass der Upload fertig ist. Wir erstellen einen
File-Eintrag und geben dir eine teilbare URL.
Basis-URL
https://storage.to/apiAlle Endpoints unten sind relativ zu dieser Basis. Beispiel: POST /upload/init bedeutet POST https://storage.to/api/upload/init.
Authentifizierung
Anonyme Uploads funktionieren ohne Authentifizierung, aber mit engen Limits. Aufrufe ohne Schlüssel sind auf 50 Dateien pro rollierende 24 Stunden pro Gerät oder IP begrenzt, plus die Bandbreitenkontingente unten, und Dateien laufen nach 3 Tagen ab.
Die Authentifizierung mit einem kostenlosen Konto schaltet frei:
- Kein tägliches Datei-Limit
- Keine Upload-Bandbreitenbegrenzung
- Uploads, die mit deinem Konto verknĂĽpft sind (sichtbar unter /dashboard)
- Premium-Funktionen (dauerhafte Dateien, mehr Speicherplatz)
- Mutationen basierend auf Eigentum (löschen, Passwort setzen, Ablauf ändern), ohne dass der visitor-token-Abgleich nötig ist
Limits auf einen Blick
| Limit | Ohne Token (anonym) | Token eines Gratis-Kontos | Token eines Bezahl-Kontos |
|---|---|---|---|
| Dateien pro Tag | 50 / 24 Stunden | Unbegrenzt | Unbegrenzt |
| Upload-Bandbreite | 100 GB / 24 Stunden (500 GB pro IP) | Unbegrenzt | Unbegrenzt |
| Maximale Dateigröße | 25 GB | 25 GB | 100 GB |
| Ablauf der Datei | Standardmäßig 3 Tage, bis zu 7 über expiry_days | Standardmäßig 3 Tage, bis zu 7 über expiry_days | Nie (Dateien bleiben dauerhaft) |
| Speicherplatz | Keiner (Dateien laufen ab) | Keiner (Dateien laufen ab) | 100 GB - 1 TB dauerhaft, je nach Tarif |
Es gibt keine Monatskontingente - alle Limits sind rollierende 24-Stunden-Fenster oder Limits pro Minute. Der Gratis-Tarif hat keinen festen Speicherplatz: Jede Datei läuft von selbst ab, es sammelt sich also nichts gegen ein Kontingent an.
Um dich zu authentifizieren, erstelle in deinem Konto ein persönliches API-Token und sende es bei jeder Anfrage als Bearer-Token:
Authorization: Bearer <token>Du musst angemeldet sein. Das vollständige Token wird nur einmal bei der Erstellung angezeigt — kopiere es an einen sicheren Ort. Du kannst ein Token jederzeit auf derselben Seite widerrufen.
Besuchertoken
Anonyme Clients brauchen eine Möglichkeit, die Inhaberschaft ihrer eigenen Uploads ohne Konto nachzuweisen. Wir verwenden ein visitor-token – eine zufällige Zeichenkette, die der Client einmal erzeugt und danach wiederverwendet. Mit jeder Anfrage senden:
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).
Bei Mutation-Endpunkten (löschen, Passwort setzen, Ablauf ändern) ist die Inhaberschaft bestätigt, wenn entweder das Visitor-Token übereinstimmt oder die Anfrage von derselben IP kommt, die die Datei erstellt hat. Beides kann verloren gehen (gelöschte Cookies, Netzwerkwechsel). Das Owner-Token ist der bevorzugte Nachweis für die Zukunft.
Owner-Token
Jeder Endpunkt zum Erstellen von Ressourcen (/upload/init multipart, /upload/confirm, /file/reserve, /collection) gibt in seiner Antwort ein owner_token zurück. Das Token ist ein signierter Nachweis der Inhaberschaft, der an diese spezielle Ressource gebunden ist—unabhängig von deiner IP oder deinem Visitor-Token.
Speichere das Token zusammen mit der Ressourcen-ID und sende es bei jeder Mutation als:
Authorization: Owner <token>Oder, wenn du bereits Authorization: Bearer fĂĽr eine authentifizierte Session verwendest, sende es so:
X-Owner-Token: <token>Der Server akzeptiert das Owner-Token als gültigen Nachweis der Inhaberschaft – zusätzlich zum bisherigen visitor-token + IP-Fallback. Clients, die das Token haben, funktionieren auch nach dem Wechsel des Netzwerks oder dem Löschen von Cookies weiter, und Clients ohne Token funktionieren weiterhin genau wie zuvor.
Tokens leben so lange wie die Ressource, sind sicher zum Speichern und laufen nicht unabhängig ab. Ein verlorenes Token bedeutet, die Kontrolle über diese Ressource (Datei/Sammlung/Upload) zu verlieren – behandle sie wie lokale Passwörter.
Fehler
Fehler folgen einem einheitlichen Schema:
{
"success": false,
"error": "Human-readable message"
}Häufige HTTP-Statuscodes:
| Code | Bedeutung |
|---|---|
200 | OK. |
201 | Erstellt. |
400 | Ungültige Anfrage (z. B. Größenlimit der Sammlung überschritten). |
401 | Passwort erforderlich oder falsch. |
403 | Nicht autorisiert (nicht der Besitzer der Ressource). |
404 | Ressource nicht gefunden oder abgelaufen. |
422 | Validierung fehlgeschlagen oder Einschränkung durch Tarif/Kontingent. |
429 | Ratelimit oder Upload-Kontingent erreicht. |
500 | Serverfehler. PrĂĽfe Status. |
Ratenbegrenzungen
Alle Ratelimits gelten pro IP. Eine 429-Antwort enthält die Standard-Header Retry-After, X-RateLimit-Limit und X-RateLimit-Remaining.
| Geltungsbereich | Limit |
|---|---|
| Upload initialisieren / bestätigen / abbrechen | 60 / Minute |
| Multipart-Abschluss | 500 / Minute |
| Multipart-Teil-URLs | 120 / Minute |
| Batch-Initialisierung / -Bestätigung | 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-Analytics / Fehler | 120 und 60 / Minute |
Upload-Kontingent: Anonyme Clients haben zwei parallele Limits – 100 GB / 24 h pro visitor-token und 500 GB / 24 h pro IP (das IP-Limit fängt tokenlosen Traffic und geteilte Netzwerke ab). Wenn eines davon überschritten wird, bekommst du einen 429 mit Details. Das ist nur ein Upload-Limit – Downloads sind unbegrenzt und ohne Drosselung (werden direkt über R2 signierte URLs bereitgestellt).
Upload
Der Drei-Schritte-Upload-Flow für jede Datei—inklusive Dateien über 5 GB (automatisch multipart). Wenn du nur einen schnellen Upload im Screenshot-Stil brauchst, schau stattdessen bei ShareX vorbei.
/upload/init60/minStarte einen Upload. Bei Dateien >50 MB ist die Antwort ein Multipart-Upload (Feld type: "multipart"); ansonsten ein einzelnes presigned PUT.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
filename | string · required | Ursprünglicher Dateiname. Max. 255 Zeichen. |
content_type | string · required | MIME-Typ. |
size | integer · required | Dateigröße in Bytes. Min. 1. |
/upload/partsOwner only120/minFordert zusätzliche Part-URLs für einen laufenden Multipart-Upload an. Wird verwendet, wenn /init weniger URLs zurückgegeben hat als du Parts hast (oder sie abgelaufen sind).
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
upload_id | string · required | Die upload_id von /init. |
part_numbers | array<int> · required | Part-Nummern, für die URLs abgerufen werden sollen. |
/upload/complete-multipartOwner only500/minSchlieĂźt einen Multipart-Upload auf R2 ab, sobald alle Parts 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/abortOwner only60/minBricht einen Multipart-Upload ab und räumt alle unvollständigen Daten auf R2 auf.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
upload_id | string · required | Der Upload, der abgebrochen werden soll. |
/upload/confirm60/minBestätige, dass der Upload abgeschlossen ist. In diesem Schritt erstellen wir den File-Eintrag und geben die freigabefähige URL zurück.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
filename | string · required | Ursprünglicher Dateiname. |
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-Checksumme zur Integritätsprüfung. |
file_id | string(9) · optional | Erfülle eine zuvor reserviert-Datei-ID. |
/file/reserve60/minReserviere eine Date-ID und eine freigabefähige URL vor die Bytes bereit sind. Praktisch, wenn du zuerst einen Link weitergeben und den Upload danach erfüllen musst. Die Berechtigung ist an dein Visitor-Token + deine IP gebunden. Schließe den Upload später mit /upload/init + /upload/confirm ab und übergib dabei file_id zur Bestätigung.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
filename | string · optional | Platzhalter-Dateiname. Standard: "Pending". |
content_type | string · optional | Platzhalter-MIME-Typ. |
/upload/init-batch500/minBatch-Äquivalent von /upload/init, optimiert für den Web-Uploader. Startet bis zu 250 Dateien in einem einzigen Round-Trip.
Wird intern vom Web-Uploader verwendet. Die meisten Clients sollten lieber single-file /upload/init verwenden.
/upload/confirm-batch500/minBatch-Äquivalent von /upload/confirm. Bestätigt viele Dateien in einem einzigen Round-Trip.
Sammlungen
Eine Sammlung gruppiert mehrere Dateien unter einer einzigen Freigabe-URL (/c/{id}). Bis zu 10.000 Dateien und insgesamt 25 GB.
/collection30/minErstelle eine neue Sammlung. Hänge Dateien danach an, indem du collection_id an /upload/confirm übergibst.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
expected_file_count | integer · optional | Hinweis für die automatische Markierung der Sammlung als bereit, sobald alle erwarteten Dateien bestätigt wurden. |
/collection/{id}/status120/minFrage den Status einer Sammlung ab. Markiert die Sammlung außerdem automatisch als bereit, wenn alle erwarteten Dateien bestätigt wurden.
/collection/{id}/readyOwner only60/minMarkiere die Sammlung als bereit zum Download. Normalerweise nicht nötig – Sammlungen werden automatisch bereit, sobald expected_file_count erreicht ist.
/collection/{id}Owner only60/minLösche eine Sammlung und alle ihre Dateien.
/collection/{id}/passwordOwner only30/minSetze ein Passwort für die Sammlung. Erfordert 4–100 Zeichen.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
password | string · required | 4–100 Zeichen. |
/collection/{id}/passwordOwner only30/minEntferne das Passwort aus der Sammlung.
/collection/{id}/verify-password10/minPrĂĽfe ein Passwort. Gibt 200 bei Erfolg zurĂĽck, 401 bei falschem Passwort.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
password | string · required |
/collection/{id}/expiryOwner only30/minÄndere die Ablaufzeit einer Sammlung.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
days | integer · optional | In 1–7 Tagen. Weglassen oder null für dauerhaft (nur Premium). |
/collection/{id}/max-downloadsOwner only30/minSetze ein Download-Limit (burn-after-N-downloads). Die Sammlung wird automatisch gelöscht, sobald es erreicht ist.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
max_downloads | integer · optional | 1–1000. Muss den aktuellen Download-Zähler übersteigen. null, um das Limit zu entfernen. |
Dateien
Alle Einstellungen auf Dateiebene (Passwort, Ablauf, max-downloads) spiegeln die Collection-Endpunkte wider. Nur fĂĽr den Owner.
/file/{id}/status120/minPrĂĽfe, ob eine Datei noch auf ihren Upload wartet.
/file/{id}Owner only60/minLösche eine Datei sofort.
/file/{id}/thumbnailOwner only120/minLade 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}/passwordOwner only30/minSetze ein Passwort für eine Datei. Erfordert 4–100 Zeichen.
/file/{id}/passwordOwner only30/minEntferne das Passwort einer Datei.
/file/{id}/verify-password10/minĂśberprĂĽfe das Passwort einer Datei.
/file/{id}/expiryOwner only30/minÄndere die Ablaufzeit einer Datei.
Request-Body
| Feld | Typ | Beschreibung |
|---|---|---|
days | integer · optional | In 1–7 Tagen. Weglassen oder null für dauerhaft (nur Premium). |
/file/{id}/max-downloadsOwner only30/minBegrenze die Gesamtzahl der Downloads einer Datei. Wird automatisch gelöscht, wenn das Limit erreicht ist.
ShareX-Upload
One-Shot-Upload-Endpunkt – sende eine Multipart-Datei und erhalte eine teilbare URL zurück. Kein Init/Confirm-Tanz. Ideal für Screenshot-Tools. Vollständige Anleitung unter /docs/sharex.
Desktop-Authentifizierung
FĂĽr authentifizierte Clients (z. B. die Desktop-App), die einen Sanctum-Token besitzen.
/userBearer tokenGibt den authentifizierten Benutzer zurĂĽck.
/auth/logoutBearer tokenWiderruft das aktuelle Zugriffstoken.
Verschiedenes
/healthLiveness-Check. Gibt 200 mit { "status": "ok" } zurück, wenn der API-Worker läuft.
/activityLive-Aktivitätsstream für den Globus auf der Startseite. Im Edge-Cache von Cloudflare gespeichert.
/bandwidth/status60/minAktuelle Upload-Kontingentnutzung für den Aufrufer – genutzt von der CLI und der Desktop-App, um die verbleibende Kapazität anzuzeigen. Das Antwortformat unterscheidet sich für authentifizierte Nutzer. Trotz des URL-Namens werden hier nur Upload-Bytes erfasst; Downloads werden nicht mitgezählt.
/app-analytics120/minSende ein Nutzungsereignis ĂĽber die CLI oder die 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-errors60/minSende einen Fehlerbericht aus der CLI oder der Desktop-App. Serverseitig dedupliziert – maximal 10 vom gleichen 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 | Stacktrace. |
version, os, os_version, arch, context | various · optional | Diagnose-Metadaten. |