REST API
Upload bestanden, maak collecties en beheer shares via HTTP. Alle antwoorden zijn JSON; voor anonieme uploads is geen API-sleutel vereist.
Introductie
De storage.to API vormt de basis voor onze CLI, desktopapp, web-uploader en elke third-party client die je wilt bouwen.
Het uploadproces bestaat uit drie stappen:
- Init — laat ons weten dat je een bestand wilt uploaden. We retourneren één of meer presigned URL's die naar Cloudflare R2 wijzen.
- Upload naar R2 — :stuur je bytes direct naar de presigned URL(s). Bytes gaan niet via onze servers.
- Bevestigen — laat ons weten dat de upload klaar is. We maken een
File-record en geven je een deelbare URL.
Basis-URL
https://storage.to/api
Alle endpoints hieronder zijn relatief aan deze basis. Voorbeeld: POST /upload/init betekent POST https://storage.to/api/upload/init.
Authenticatie
De meeste endpoints vereisen geen authenticatie. Anonieme uploads zijn een kernfunctie.
Authenticatie is optioneel en ontgrendelt:
- Uploads gekoppeld aan je account (zichtbaar op /dashboard)
- Premiumfuncties (permanente bestanden, meer opslag)
- Mutaties op basis van eigendom (verwijderen, wachtwoord instellen, vervaldatum wijzigen) zonder dat je de visitor-token match nodig hebt
We gebruiken Laravel Sanctum bearer tokens. Vraag een token aan via de desktop OAuth-overdracht of via de web-login en stuur het vervolgens als:
Authorization: Bearer <token>
Bezoekerstoken
Anonieme clients hebben een manier nodig om eigendom van hun eigen uploads te bewijzen zonder een account. We gebruiken een visitor token — een willekeurige string die de client één keer genereert en daarna hergebruikt. Stuur het mee met elke request:
X-Visitor-Token: <random-string>
Op het web wordt de token automatisch opgeslagen in de visitor_token-cookie. De CLI slaat deze op op ~/.config/storageto/token (zie CLI-documentatie).
Voor mutatie-endpoints (verwijderen, wachtwoord instellen, vervaldatum wijzigen) wordt eigendom bevestigd als of de bezoeker-token overeenkomt met of het verzoek afkomstig is van hetzelfde IP dat het bestand heeft aangemaakt. Beide kunnen verloren gaan (cookies gewist, netwerkwijzigingen). De owner-token is het voorkeursbewijs voor de toekomst.
Eigenaars-token
Elk endpoint dat een resource aanmaakt (/upload/init multipart, /upload/confirm, /upload/reserve, /collection) retourneert een owner_token in zijn antwoord. De token is een ondertekend bewijs van eigendom dat gekoppeld is aan die specifieke resource, onafhankelijk van je IP of bezoeker-token.
Bewaar de token samen met de resource-ID en stuur deze bij elke mutatie als:
Authorization: Owner <token>
Of, als je al Authorization: Bearer gebruikt voor een geauthenticeerde sessie, stuur het dan als:
X-Owner-Token: <token>
De server accepteert de owner-token als geldig bewijs van eigendom naast de legacy visitor token + IP-fallback — clients die de token hebben blijven werken na het wisselen van netwerk of het wissen van cookies, en clients die de token niet hebben werken nog steeds precies zoals voorheen.
Tokens blijven bestaan zolang de resource bestaat, zijn veilig om op te slaan en verlopen niet onafhankelijk. Een verloren token betekent dat je de controle over die resource verliest (bestand/collectie/upload) — behandel ze als lokale wachtwoorden.
Fouten
Fouten volgen een consistent patroon:
{
"success": false,
"error": "Human-readable message"
}
Veelvoorkomende HTTP-statuscodes:
| Code | Betekenis |
|---|---|
200 | OK. |
201 | Aangemaakt. |
400 | Slecht verzoek (bijv. limiet voor collectiegrootte overschreden). |
401 | Wachtwoord vereist of onjuist. |
403 | Niet geautoriseerd (niet de eigenaar van de resource). |
404 | Resource niet gevonden of verlopen. |
422 | Validatie mislukt, of beperking door abonnement/quota. |
429 | Snelheidslimiet bereikt of uploadquota overschreden. |
500 | Serverfout. Controleer status. |
Snelheidslimieten
Alle snelheidslimieten zijn per IP. Een 429-antwoord bevat de standaard Retry-After-, X-RateLimit-Limit- en X-RateLimit-Remaining-headers.
| Bereik | Limiet |
|---|---|
| Upload initialiseren / bevestigen / afbreken | 60 / minuut |
| Multipart voltooiing | 500 / minuut |
| Multipart part-URL's | 120 / minuut |
| Batch initialiseren / bevestigen | 500 / minuut |
| Status-polls (bestand & collectie) | 120 / minuut |
| Instellingen (wachtwoord, vervaldatum, max-downloads) | 30 / minuut |
| Wachtwoordverificatie | 10 / minuut |
| Collectie aanmaken | 30 / minuut |
| Beheren (klaarzetten, verwijderen) | 60 / minuut |
| Thumbnail uploaden | 120 / minuut |
| ShareX uploaden | 20 / dag |
| App-analytics / fouten | 120 en 60 / minuut |
Uploadquota: anonieme clients hebben twee limieten die parallel lopen — 100 GB / 24 u per visitor token en 500 GB / 24 u per IP (de IP-limiet vangt verkeer zonder token en gedeelde netwerken). Als één van beide wordt overschreden, krijg je een 429 met details. Dit is alleen een upload quotum — downloads zijn onbeperkt en niet vertraagd (geleverd direct via R2-gesigneerde URL's).
Upload
De uploadflow in drie stappen voor elk bestand, inclusief bestanden groter dan 5 GB (automatisch multipart). Als je alleen een snelle upload in screenshot-stijl nodig hebt, kijk dan in plaats daarvan naar ShareX.
/upload/init
60/min
Start een upload. Voor bestanden >50 MB is het antwoord een multipart-upload (type: "multipart"-veld); anders een enkele presigned PUT.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
filename | string · required | Originele bestandsnaam. Maximaal 255 tekens. |
content_type | string · required | MIME-type. |
size | integer · required | Bestandsgrootte in bytes. Minimaal 1. |
/upload/parts
Owner only
120/min
Vraag extra URL's op voor een multipart-upload die nog bezig is. Wordt gebruikt wanneer /init minder URL's teruggeeft dan je hebt (of wanneer ze zijn verlopen).
Request body
| Veld | Type | Beschrijving |
|---|---|---|
upload_id | string · required | De upload_id uit /init. |
part_numbers | array<int> · required | Partijnummers waarvoor je URL's wilt ophalen. |
/upload/complete-multipart
Owner only
500/min
Rond een multipart-upload op R2 af zodra alle delen zijn geüpload.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
upload_id | string · required | De upload_id uit /init. |
parts | array · required | Elke entry: { partNumber, etag } uit de R2-respons. |
/upload/abort
Owner only
60/min
Annuleer een multipart-upload en ruim eventuele gedeeltelijke data op op R2.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
upload_id | string · required | De upload die moet worden afgebroken. |
/upload/confirm
60/min
Bevestig dat de upload is voltooid. Dit is wanneer we het File-record aanmaken en de deelbare URL teruggeven.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
filename | string · required | Originele bestandsnaam. |
size | integer · required | Bestandsgrootte in bytes. |
content_type | string · required | MIME-type. |
r2_key | string · required | De r2_key uit /init. |
collection_id | string · optional | Koppel aan een collectie. |
crc32 | integer · optional | CRC32-checksum voor integriteitscontrole. |
file_id | string(9) · optional | Voldoe een eerder gereserveerd file-ID. |
/file/reserve
60/min
Reserveer een file-ID en deelbare URL voor de bytes klaar zijn. Handig wanneer je eerst een link wilt doorgeven en de upload daarna wilt afronden. Eigendom is gekoppeld aan je visitor-token + IP. Rond de upload later af met /upload/init + /upload/confirm en geef file_id door om te bevestigen.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
filename | string · optional | Placeholder-bestandsnaam. Standaard: "Pending". |
content_type | string · optional | Placeholder MIME-type. |
/upload/init-batch
500/min
Batch-equivalent van /upload/init, geoptimaliseerd voor de web-uploader. Start tot 250 bestanden in één round-trip.
Wordt intern gebruikt door de web-uploader. De meeste clients moeten de voorkeur geven aan single-file /upload/init.
/upload/confirm-batch
500/min
Batch-equivalent van /upload/confirm. Bevestigt veel bestanden in één round-trip.
Collecties
Een collectie groepeert meerdere bestanden onder één deelbare URL (/c/{id}). Tot 10.000 bestanden en 25 GB totaal.
/collection
30/min
Maak een nieuwe collectie. Koppel bestanden achteraf door collection_id door te geven op /upload/confirm.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
expected_file_count | integer · optional | Tip voor automatisch markeren van de collectie als klaar zodra alle verwachte bestanden zijn bevestigd. |
/collection/{id}/status
120/min
Controleer de status van een collectie. Markeert de collectie ook automatisch als klaar als alle verwachte bestanden zijn bevestigd.
/collection/{id}/ready
Owner only
60/min
Markeer de collectie als klaar om te downloaden. Meestal niet nodig — collecties worden automatisch klaar zodra expected_file_count is bereikt.
/collection/{id}
Owner only
60/min
Verwijder een collectie en al haar bestanden.
/collection/{id}/password
Owner only
30/min
Stel een wachtwoord in voor de collectie. Vereist 4–100 tekens.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
password | string · required | 4–100 tekens. |
/collection/{id}/password
Owner only
30/min
Verwijder het wachtwoord uit een collectie.
/collection/{id}/verify-password
10/min
Controleer een wachtwoord. Geeft 200 terug bij succes, 401 bij een onjuist wachtwoord.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
password | string · required |
/collection/{id}/expiry
Owner only
30/min
Wijzig de vervaldatum van een collectie.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
days | integer · optional | 1–7 dagen vanaf nu. Laat weg of gebruik null voor permanent (alleen premium). |
/collection/{id}/max-downloads
Owner only
30/min
Stel een downloadlimiet in (burn-after-N-downloads). De collectie wordt automatisch verwijderd zodra de limiet is bereikt.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
max_downloads | integer · optional | 1–1000. Moet hoger zijn dan het huidige aantal downloads. null om de limiet te verwijderen. |
Bestanden
Alle instellingen op bestandsniveau (wachtwoord, vervaldatum, max-downloads) spiegelen de collectie-endpoints. Alleen voor de eigenaar.
/file/{id}/status
120/min
Controleer of een bestand nog wacht op de upload.
/file/{id}
Owner only
60/min
Verwijder een bestand direct.
/file/{id}/thumbnail
Owner only
120/min
Upload een thumbnail-afbeelding voor een video- of afbeeldingsbestand (wordt gebruikt op de downloadpagina). Max 2 MB.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
thumbnail | image · required | Multipart-upload. Max 2 MB. |
/file/{id}/password
Owner only
30/min
Stel een wachtwoord in voor een bestand. Vereist 4–100 tekens.
/file/{id}/password
Owner only
30/min
Verwijder het wachtwoord van een bestand.
/file/{id}/verify-password
10/min
Controleer het wachtwoord van een bestand.
/file/{id}/expiry
Owner only
30/min
Wijzig de vervaldatum van een bestand.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
days | integer · optional | 1–7 dagen vanaf nu. Laat weg of gebruik null voor permanent (alleen premium). |
/file/{id}/max-downloads
Owner only
30/min
Beperk het totale aantal downloads van een bestand. Wordt automatisch verwijderd zodra de limiet is bereikt.
ShareX uploaden
One-shot upload-endpoint — stuur een multipart-bestand en ontvang een deelbare URL terug. Geen init/confirm-dans. Ideaal voor screenshot-tools. Volledige setup-gids op /nl/docs/sharex.
Desktop-authenticatie
Voor geauthenticeerde clients (bijv. de desktopapp) met een Sanctum-token.
/user
Bearer token
Geef de geauthenticeerde gebruiker terug.
/auth/logout
Bearer token
Intrek het huidige toegangstoken.
Overig
/health
Health check. Stuurt een ping naar de database, R2-opslag en de Redis-cache. Geeft 200 terug als alles groen is, anders 503.
/activity
Live activiteitenstream voor de homepageglobe. Gecachet op de Cloudflare-edge.
/bandwidth/status
60/min
Huidig quotumverbruik voor uploads van de aanroeper — gebruikt door de CLI en desktopapp om de resterende capaciteit te tonen. De responsevorm verschilt voor geauthenticeerde gebruikers. Ondanks de naam van de URL volgt dit alleen upload bytes; downloads worden niet meegerekend.
/app-analytics
120/min
Verstuur een gebruiksgebeurtenis vanuit de CLI of desktopapp.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
app | string · required | desktop, cli of web. |
version | string · optional | Clientversie. |
event | string · required | Gebeurtenisnaam, bijvoorbeeld upload_complete. |
context | object · optional | Extra metadata. |
/app-errors
60/min
Verstuur een foutrapport vanuit de CLI of desktopapp. Server-side gededupliceerd — maximaal 10 van dezelfde fout per uur.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
app | string · required | desktop, cli of web. |
type | string · required | Foutklasse/type. |
message | string · required | Foutmelding. |
stack | string · optional | Stack trace. |
version, os, os_version, arch, context | various · optional | Diagnostische metadata. |