REST API
Upload bestanden, maak collecties en beheer shares via HTTP. Alle antwoorden zijn JSON; voor anonieme uploads is geen API-sleutel vereist.
Hoe uploads werken
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:
PUT je bytes direct naar de presigned URL(s). Bytes gaan niet via onze servers.File-record en geven je een deelbare URL.Alle endpoints hieronder zijn relatief aan deze basis. Voorbeeld: POST /upload/init betekent POST https://storage.to/api/upload/init.
Authenticatie
Anonieme uploads werken zonder authenticatie, maar met strikte limieten. Aanroepen zonder sleutel zijn beperkt tot 50 bestanden per doorlopende 24 uur per apparaat of IP, plus de bandbreedtequota hieronder, en bestanden verlopen na 3 dagen.
Authenticeren met een gratis account ontgrendelt:
- Geen dagelijkse bestandslimiet
- Geen uploadbandbreedtequotum
- 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
Limieten in één oogopslag
expiry_daysexpiry_daysEr zijn geen maandelijkse quota - alle limieten zijn voortschrijdende 24-uursvensters of limieten per minuut. Het gratis abonnement heeft geen vaste opslagruimte: elk bestand verloopt vanzelf, dus er stapelt zich niets op tegen een quotum.
Eigenaarschap bewijzen
/upload/init multipart, /upload/confirm, /file/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. Tokens 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 (bestand/collectie/upload) verliest — behandel ze als lokale wachtwoorden.# of, naast een Bearer-sessie
X-Owner-Token: <token>
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.
Fouten
Fouten volgen een consistent patroon: { "success": false, "error": "…" }
Snelheidslimieten
Alle snelheidslimieten zijn per IP. Een 429-antwoord bevat de standaard Retry-After-, X-RateLimit-Limit- en X-RateLimit-Remaining-headers.
Uploadquota: anonieme clients hebben twee limieten tegelijk actief - 100 GB / 24 u per visitor token en 500 GB / 24 u per IP (de IP-limiet vangt verkeer zonder token en gedeelde netwerken). Zodra één van beide wordt overschreden krijg je een 429 met details. Dit is alleen een upload-quota - downloads zijn onbeperkt en niet beperkt.
Upload
8 endpointsDe 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.
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. |
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 }'
{ "success": true, "type": "single", "upload_url": "https://r2.cloudflarestorage.com/...signed...", "headers": { "Host": ["..."] }, "r2_key": "uuid-abc123" }
{ "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_..." }
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. |
curl -X POST https://storage.to/api/upload/parts \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ...", "part_numbers": [3, 4] }'
{ "success": true, "part_urls": [ { "partNumber": 3, "url": "https://..." }, { "partNumber": 4, "url": "https://..." } ] }
Rond een multipart-upload 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 respons van de deel-upload. |
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...\"" } ] }'
{ "success": true }
Annuleer een multipart-upload en ruim eventuele gedeeltelijke data op.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
upload_id | string · required | De upload die moet worden afgebroken. |
curl -X POST https://storage.to/api/upload/abort \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ..." }'
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. |
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" }'
{ "success": true, "file": { "id": "FQxyz1234", "url": "https://storage.to/FQxyz1234", "filename": "report.pdf", "size": 2202009, "human_size": "2.1 MB", "expires_at": "2026-04-15T12:00:00Z" }, "owner_token": "owner_v1_..." }
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. |
curl -X POST https://storage.to/api/file/reserve \ -H "X-Visitor-Token: abc123"
{ "success": true, "file": { "id": "FQxyz1234", "url": "https://storage.to/FQxyz1234", "expires_at": "2026-04-12T18:00:00Z" }, "owner_token": "owner_v1_..." }
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.
Batch-equivalent van /upload/confirm. Bevestigt veel bestanden in één round-trip.
Collecties
9 endpointsEen collectie groepeert meerdere bestanden onder één deelbare URL (/c/{id}). Tot 10.000 bestanden en 25 GB totaal.
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. |
curl -X POST https://storage.to/api/collection \ -H "Content-Type: application/json" \ -H "X-Visitor-Token: abc123" \ -d '{ "expected_file_count": 3 }'
{ "success": true, "collection": { "id": "ABC123xyz", "url": "https://storage.to/c/ABC123xyz", "expires_at": "2026-04-15T12:00:00Z" }, "owner_token": "owner_v1_..." }
Controleer de status van een collectie. Markeert de collectie ook automatisch als klaar als alle verwachte bestanden zijn bevestigd.
curl https://storage.to/api/collection/ABC123xyz/status
{ "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" }
Markeer de collectie als klaar om te downloaden. Meestal niet nodig — collecties worden automatisch klaar zodra expected_file_count is bereikt.
Verwijder een collectie en al haar bestanden.
Stel een wachtwoord in voor de collectie. Vereist 4–100 tekens.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
password | string · required | 4–100 tekens. |
curl -X POST https://storage.to/api/collection/ABC123xyz/password \ -H "X-Visitor-Token: abc123" \ -d '{ "password": "hunter22" }'
Verwijder het wachtwoord uit een collectie.
Controleer een wachtwoord. Geeft 200 terug bij succes, 401 bij een onjuist wachtwoord.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
password | string · required |
Wijzig de vervaldatum van een collectie.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
days | integer · optional | Over 1–7 dagen, maar nooit later dan 7 dagen na de upload (of de huidige vervaldatum, als die later is). Weglaten of null voor permanent (alleen premium). |
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
8 endpointsAlle instellingen op bestandsniveau (wachtwoord, vervaldatum, max-downloads) spiegelen de collectie-endpoints. Alleen voor de eigenaar.
Controleer of een bestand nog wacht op de upload.
{ "pending": false }
Verwijder een bestand direct.
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. |
{ "success": true, "thumbnail_url": "https://..." }
Stel een wachtwoord in voor een bestand. Vereist 4–100 tekens.
Verwijder het wachtwoord van een bestand.
Controleer het wachtwoord van een bestand.
Wijzig de vervaldatum van een bestand.
Request body
| Veld | Type | Beschrijving |
|---|---|---|
days | integer · optional | Over 1–7 dagen, maar nooit later dan 7 dagen na de upload (of de huidige vervaldatum, als die later is). Weglaten of null voor permanent (alleen premium). |
Beperk het totale aantal downloads van een bestand. Wordt automatisch verwijderd zodra de limiet is bereikt.
Desktop-authenticatie
2 endpointsVoor ingelogde clients, zoals de desktop-app, die een Bearer-token hebben.
Geef de geauthenticeerde gebruiker terug.
curl https://storage.to/api/user \ -H "Authorization: Bearer <token>"
{ "id": 42, "name": "Ada", "email": "ada@example.com", "is_premium": true }
Intrek het huidige toegangstoken.
Overig
5 endpointsStatus, quota en client-telemetrie.
Liveness-check. Geeft 200 met { "status": "ok" } terug wanneer de API-worker draait.
{ "status": "ok" }
Live activiteitenstream voor de homepageglobe. Gecachet op de edge.
Huidig upload-quota-gebruik voor de aanroeper — gebruikt door de CLI en desktop-app om de resterende capaciteit te tonen. Het response-formaat verschilt voor geauthenticeerde gebruikers. Ondanks de naam van de URL houdt dit alleen upload bytes bij; downloads worden niet meegerekend.
{ "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 }
{ "success": true, "authenticated": true, "plan": "premium" }
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. |
Dien een foutmelding in via de CLI of desktop-app. 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. |