API REST
Envoyez des fichiers, créez des collections et gérez les partages via HTTP. Toutes les réponses sont au format JSON ; aucune clé API n’est requise pour les envois anonymes.
Introduction
L’API storage.to alimente notre CLI, application desktop, uploader web, et tout client tiers que vous souhaitez créer.
Le processus d’envoi se fait en trois étapes :
- Initialiser - dites-nous que vous souhaitez envoyer un fichier. Nous renvoyons une ou plusieurs URL pré-signées pointant vers Cloudflare R2.
- Envoyer vers R2 -
PUTvos octets directement vers l(es) URL(s) pré-signée(s). Les octets ne passent pas par nos serveurs. - Confirmer - dites-nous que l’envoi est terminé. Nous créons un enregistrement
Fileet vous fournissons une URL partageable.
URL de base
https://storage.to/apiTous les endpoints ci-dessous sont relatifs à cette base. Exemple : POST /upload/init signifie POST https://storage.to/api/upload/init.
Authentification
Les envois anonymes fonctionnent sans authentification, mais avec des limites strictes. Les appels sans clé sont limités à 50 fichiers par 24 heures glissantes par appareil ou IP, plus les quotas de bande passante ci-dessous, et les fichiers expirent après 3 jours.
S'authentifier avec un compte gratuit débloque :
- Pas de plafond quotidien de fichiers
- Pas de quota de bande passante d'envoi
- Envois associés à votre compte (visibles à /dashboard)
- Fonctionnalités premium (fichiers permanents, stockage plus important)
- Modifications basées sur la propriété (supprimer, définir un mot de passe, modifier l’expiration) sans avoir besoin que le visitor-token corresponde
Limites en un coup d'œil
| Limite | Sans jeton (anonyme) | Jeton de compte gratuit | Jeton de compte payant |
|---|---|---|---|
| Fichiers par jour | 50 / 24 heures | Illimité | Illimité |
| Bande passante d'envoi | 100 GB / 24 heures (500 GB par IP) | Illimité | Illimité |
| Taille max du fichier | 25 GB | 25 GB | 100 GB |
| Expiration du fichier | 3 jours par défaut, jusqu'à 7 via expiry_days | 3 jours par défaut, jusqu'à 7 via expiry_days | Jamais (les fichiers sont permanents) |
| Espace de stockage | Aucun (les fichiers expirent) | Aucun (les fichiers expirent) | 100 Go - 1 To permanent, selon l'offre |
Il n'y a pas de quotas mensuels : toutes les limites sont des fenêtres glissantes de 24 heures ou des limites par minute. L'offre gratuite n'a pas d'espace de stockage fixe : chaque fichier expire de lui-même, rien ne s'accumule donc contre un quota.
Pour vous authentifier, générez un jeton API personnel depuis votre compte et envoyez-le comme jeton porteur (bearer) à chaque requête :
Authorization: Bearer <token>Vous devez être connecté. Le jeton complet n’est affiché qu’une seule fois lors de sa création : copiez-le dans un endroit sûr. Vous pouvez révoquer un jeton à tout moment depuis la même page.
Jeton visiteur
Les clients anonymes ont besoin d’un moyen de prouver qu’ils sont bien propriétaires de leurs propres envois, sans compte. Nous utilisons un visitor token - une chaîne aléatoire que le client génère une fois et réutilise. Envoyez-la avec chaque requête :
X-Visitor-Token: <random-string>Sur le web, le jeton est stocké automatiquement dans le cookie visitor_token. La CLI le stocke à ~/.config/storageto/token (voir Docs CLI).
Pour les endpoints de mutation (suppression, définition du mot de passe, changement de l’expiration), la propriété est confirmée si soit le token du visiteur correspond à ou si la requête provient de la même IP que celle qui a créé le fichier. Les deux peuvent être perdus (cookies effacés, changements de réseau). À l’avenir, la preuve préférée est token du propriétaire.
Jeton propriétaire
Chaque endpoint qui crée une ressource (/upload/init multipart, /upload/confirm, /file/reserve, /collection) renvoie un owner_token dans sa réponse. Le token est une preuve signée de propriété liée à cette ressource précise, indépendante de votre IP ou de votre token de visiteur.
Conservez le token avec l’ID de la ressource et envoyez-le pour toute mutation comme :
Authorization: Owner <token>Ou, si vous utilisez déjà Authorization: Bearer pour une session authentifiée, envoyez-le comme :
X-Owner-Token: <token>Le serveur accepte le token du propriétaire comme preuve de propriété valide, en plus du mécanisme de secours historique visitor token + IP. Les clients qui possèdent le token continuent de fonctionner après avoir changé de réseau ou effacé les cookies, et les clients qui ne l’ont pas fonctionnent exactement comme avant.
Les tokens durent aussi longtemps que la ressource, sont sûrs à conserver et n’expirent pas indépendamment. Un token perdu signifie perdre le contrôle de cette ressource (fichier/collection/envoi) — traitez-les comme des mots de passe locaux.
Erreurs
Les erreurs suivent une structure cohérente :
{
"success": false,
"error": "Human-readable message"
}Codes HTTP courants :
| Code | Signification |
|---|---|
200 | OK. |
201 | Créé. |
400 | Requête incorrecte (par ex. limite de taille de la collection dépassée). |
401 | Mot de passe requis ou incorrect. |
403 | Non autorisé (pas le propriétaire de la ressource). |
404 | Ressource introuvable ou expirée. |
422 | Échec de la validation, ou restriction liée au plan / au quota. |
429 | Limite de débit atteinte ou quota de téléversement dépassé. |
500 | Erreur serveur. Vérifiez statut. |
Limites de débit
Toutes les limites de débit sont par IP. Une réponse 429 inclut les en-têtes standards Retry-After, X-RateLimit-Limit et X-RateLimit-Remaining.
| Portée | Limite |
|---|---|
| Initialisation / confirmation / annulation du téléversement | 60 / minute |
| Finalisation multipart | 500 / minute |
| URLs des parties multipart | 120 / minute |
| Initialisation / confirmation en lot | 500 / minute |
| Vérifications de statut (fichier & collection) | 120 / minute |
| Paramètres (mot de passe, expiration, max de téléchargements) | 30 / minute |
| Vérification du mot de passe | 10 / minute |
| Création de collection | 30 / minute |
| Gérer (prêt, supprimer) | 60 / minute |
| Téléversement de la vignette | 120 / minute |
| Téléversement ShareX | 20 / jour |
| Analytique de l’app / erreurs | 120 et 60 / minute |
Quota de téléversement : Les clients anonymes ont deux plafonds en parallèle — 100 Go / 24 h par visitor token et 500 Go / 24 h par IP (le plafond IP capte le trafic sans token et les réseaux partagés). Dès qu’un plafond est dépassé, vous obtenez un 429 avec des détails. C’est un quota téléversement uniquement — les téléchargements sont illimités et non limités (servis directement via des URL signées R2).
Téléverser
Le flux de téléversement en trois étapes pour n’importe quel fichier, y compris les fichiers de plus de 5 Go (multipart automatiquement). Si vous avez seulement besoin d’un téléversement rapide de type capture d’écran, regardez plutôt ShareX.
/upload/init60/minDémarrez un téléversement. Pour les fichiers >50 Mo, la réponse est un téléversement multipart (champ type: "multipart") ; sinon, un seul PUT pré-signé.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
filename | string · required | Nom de fichier original. Max 255 caractères. |
content_type | string · required | Type MIME. |
size | integer · required | Taille du fichier en octets. Min 1. |
/upload/partsOwner only120/minDemande des URL supplémentaires pour les parties d’un upload multipart en cours. Utilisé quand /init a renvoyé moins d’URL que vous n’avez de parties (ou qu’elles ont expiré).
Corps de la requête
| Champ | Type | Description |
|---|---|---|
upload_id | string · required | L’ upload_id provenant de /init. |
part_numbers | array<int> · required | Numéros de parties pour lesquels obtenir des URL. |
/upload/complete-multipartOwner only500/minFinalise un upload multipart sur R2 une fois que toutes les parties sont téléversées.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
upload_id | string · required | L’ upload_id provenant de /init. |
parts | array · required | Chaque entrée : { partNumber, etag } depuis la réponse R2. |
/upload/abortOwner only60/minAnnule un upload multipart et nettoie toute donnée partielle sur R2.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
upload_id | string · required | L’upload à annuler. |
/upload/confirm60/minConfirme que l’upload est terminé. C’est à ce moment que nous créons l’enregistrement File et renvoyons l’URL partageable.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
filename | string · required | Nom de fichier original. |
size | integer · required | Taille du fichier en octets. |
content_type | string · required | Type MIME. |
r2_key | string · required | L’ r2_key provenant de /init. |
collection_id | string · optional | Ajouter à une collection. |
crc32 | integer · optional | Somme de contrôle CRC32 pour la vérification d’intégrité. |
file_id | string(9) · optional | Réalise (fulfil) un identifiant de fichier réservé précédemment créé. |
/file/reserve60/minRéserve un identifiant de fichier et une URL partageable avant que les octets soient prêts. Pratique quand vous devez d’abord partager un lien, puis finaliser l’upload ensuite. La propriété est liée à votre token de visiteur + IP. Terminez l’upload plus tard avec /upload/init + /upload/confirm, en passant file_id à la confirmation.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
filename | string · optional | Nom de fichier fictif. Par défaut : "Pending". |
content_type | string · optional | Type MIME fictif. |
/upload/init-batch500/minÉquivalent en lot de /upload/init, optimisé pour l’uploader web. Démarre jusqu’à 250 fichiers en un seul aller-retour.
Utilisé en interne par l’uploader web. La plupart des clients devraient préférer /upload/init pour un seul fichier.
/upload/confirm-batch500/minÉquivalent en lot de /upload/confirm. Confirme de nombreux fichiers en un seul aller-retour.
Collections
Une collection regroupe plusieurs fichiers sous une seule URL de partage (/c/{id}). Jusqu’à 10 000 fichiers et 25 Go au total.
/collection30/minCréez une nouvelle collection. Ajoutez les fichiers ensuite en passant collection_id sur /upload/confirm.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
expected_file_count | integer · optional | Indication pour marquer automatiquement la collection comme prête une fois que tous les fichiers attendus ont été confirmés. |
/collection/{id}/status120/minInterroge l’état d’une collection. Marque aussi automatiquement la collection comme prête si tous les fichiers attendus ont été confirmés.
/collection/{id}/readyOwner only60/minMarquez la collection comme prête au téléchargement. Pas généralement nécessaire — les collections deviennent automatiquement prêtes une fois que expected_file_count est atteint.
/collection/{id}Owner only60/minSupprime une collection et tous ses fichiers.
/collection/{id}/passwordOwner only30/minDéfinit un mot de passe pour la collection. Nécessite 4 à 100 caractères.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
password | string · required | 4–100 caractères. |
/collection/{id}/passwordOwner only30/minRetire le mot de passe d’une collection.
/collection/{id}/verify-password10/minVérifie un mot de passe. Renvoie 200 en cas de succès, 401 si le mot de passe est incorrect.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
password | string · required |
/collection/{id}/expiryOwner only30/minModifier l’expiration d’une collection.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
days | integer · optional | Dans 1 à 7 jours. Omettez ou null pour une durée permanente (premium uniquement). |
/collection/{id}/max-downloadsOwner only30/minDéfinit une limite de téléchargements (burn-after-N-downloads). La collection est supprimée automatiquement une fois atteinte.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
max_downloads | integer · optional | 1–1000. Doit dépasser le nombre actuel de téléchargements. null pour supprimer la limite. |
Fichiers
Tous les paramètres au niveau du fichier (mot de passe, expiration, max-downloads) reflètent les endpoints de la collection. Réservé au propriétaire.
/file/{id}/status120/minVérifie si un fichier est encore en attente de son upload.
/file/{id}Owner only60/minSupprime un fichier immédiatement.
/file/{id}/thumbnailOwner only120/minTéléverse une image miniature pour un fichier vidéo ou image (utilisée sur la page de téléchargement). Max 2 Mo.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
thumbnail | image · required | Upload multipart. Max 2 Mo. |
/file/{id}/passwordOwner only30/minDéfinit un mot de passe pour un fichier. Nécessite 4 à 100 caractères.
/file/{id}/passwordOwner only30/minSupprimer le mot de passe d’un fichier.
/file/{id}/verify-password10/minVérifier le mot de passe d’un fichier.
/file/{id}/expiryOwner only30/minModifier l’expiration d’un fichier.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
days | integer · optional | Dans 1 à 7 jours. Omettez ou null pour une durée permanente (premium uniquement). |
/file/{id}/max-downloadsOwner only30/minLimiter le nombre total de téléchargements d’un fichier. Suppression automatique une fois atteint.
Téléversement ShareX
Point d’envoi « one-shot » — envoyez un fichier multipart, recevez une URL partageable en retour. Pas de danse init/confirm. Idéal pour les outils de capture d’écran. Guide complet de configuration à /docs/sharex.
Authentification bureau
Pour les clients authentifiés (par ex. l’application desktop) disposant d’un token Sanctum.
/userBearer tokenRetourne l’utilisateur authentifié.
/auth/logoutBearer tokenRévoquer le jeton d’accès actuel.
Divers
/healthContrôle de disponibilité. Renvoie 200 avec { "status": "ok" } lorsque le worker de l'API répond.
/activityFlux d’activité en direct pour le globe de la page d’accueil. Mis en cache sur les serveurs edge de Cloudflare.
/bandwidth/status60/minConsommation actuelle du quota d’envoi pour l’appelant — utilisée par la CLI et l’application bureau pour afficher la capacité restante. La forme de la réponse diffère pour les utilisateurs authentifiés. Malgré le nom de l’URL, cela ne suit que les octets téléversement ; les téléchargements ne sont pas comptés.
/app-analytics120/minEnvoyer un événement d’utilisation depuis la CLI ou l’application de bureau.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
app | string · required | desktop, cli ou web. |
version | string · optional | Version du client. |
event | string · required | Nom de l’événement, par ex. upload_complete. |
context | object · optional | Métadonnées supplémentaires. |
/app-errors60/minEnvoyez un rapport d’erreur depuis la CLI ou l’application bureau. Déduplication côté serveur — maximum 10 fois la même erreur par heure.
Corps de la requête
| Champ | Type | Description |
|---|---|---|
app | string · required | desktop, cli ou web. |
type | string · required | Classe/type d’erreur. |
message | string · required | Message d’erreur. |
stack | string · optional | Trace de la pile. |
version, os, os_version, arch, context | various · optional | Métadonnées de diagnostic. |