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 — :envoyez vos 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/api
Tous les endpoints ci-dessous sont relatifs à cette base. Exemple : POST /upload/init signifie POST https://storage.to/api/upload/init.
Authentification
La plupart des endpoints ne nécessitent pas d’authentification. Les envois anonymes sont une fonctionnalité essentielle.
L’authentification est facultative et permet :
- 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
Nous utilisons des jetons porteurs Laravel Sanctum. Obtenez un jeton via la passerelle OAuth du desktop ou la connexion web, puis envoyez-le comme :
Authorization: Bearer <token>
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, /upload/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 détiennent 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, peuvent être conservés sans risque et n’expirent pas indépendamment. Un token perdu signifie perdre le contrôle de cette ressource (fichier/collection/téléversement) — 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 détecte le trafic sans jeton et les réseaux partagés). Quand l’un des deux 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 depuis 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/init
60/min
Dé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/parts
Owner only
120/min
Demande 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-multipart
Owner only
500/min
Finalise 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/abort
Owner only
60/min
Annule 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/confirm
60/min
Confirme 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/reserve
60/min
Ré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-batch
500/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-batch
500/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.
/collection
30/min
Cré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}/status
120/min
Interroge l’état d’une collection. Marque aussi automatiquement la collection comme prête si tous les fichiers attendus ont été confirmés.
/collection/{id}/ready
Owner only
60/min
Marque la collection comme prête au téléchargement. Pas généralement nécessaire — les collections deviennent automatiquement prêtes une fois expected_file_count atteint.
/collection/{id}
Owner only
60/min
Supprime une collection et tous ses fichiers.
/collection/{id}/password
Owner only
30/min
Dé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}/password
Owner only
30/min
Retire le mot de passe d’une collection.
/collection/{id}/verify-password
10/min
Vé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}/expiry
Owner only
30/min
Modifier 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-downloads
Owner only
30/min
Dé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}/status
120/min
Vérifie si un fichier est encore en attente de son upload.
/file/{id}
Owner only
60/min
Supprime un fichier immédiatement.
/file/{id}/thumbnail
Owner only
120/min
Té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}/password
Owner only
30/min
Définit un mot de passe pour un fichier. Nécessite 4 à 100 caractères.
/file/{id}/password
Owner only
30/min
Supprimer le mot de passe d’un fichier.
/file/{id}/verify-password
10/min
Vérifier le mot de passe d’un fichier.
/file/{id}/expiry
Owner only
30/min
Modifier 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-downloads
Owner only
30/min
Limiter le nombre total de téléchargements d’un fichier. Suppression automatique une fois atteint.
Téléversement ShareX
Endpoint d’upload en une seule fois — envoyez un fichier multipart, recevez une URL partageable. Pas de danse init/confirm. Idéal pour les outils de capture d’écran. Guide de configuration complet à /fr/docs/sharex.
Authentification bureau
Pour les clients authentifiés (par ex. l’application desktop) disposant d’un token Sanctum.
/user
Bearer token
Retourne l’utilisateur authentifié.
/auth/logout
Bearer token
Révoquer le jeton d’accès actuel.
Divers
/health
Vérification de santé. Ping la base de données, le stockage R2 et le cache Redis. Renvoie 200 si tout est au vert, 503 sinon.
/activity
Flux d’activité en direct pour le globe de la page d’accueil. Mis en cache sur les serveurs edge de Cloudflare.
/bandwidth/status
60/min
Utilisation actuelle du quota de téléchargement pour l’appelant — utilisée par la CLI et l’application de 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 suit uniquement les téléversement octets ; les téléchargements ne sont pas comptés.
/app-analytics
120/min
Envoyer 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-errors
60/min
Envoyer un rapport d’erreur depuis la CLI ou l’application de bureau. Dédupliqué côté serveur — max 10 de 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. |