REST API
Sube archivos, crea colecciones y gestiona compartidos vía HTTP. Todas las respuestas son JSON; no se requiere clave API para subidas anónimas.
Introducción
La API de storage.to impulsa nuestro CLI, aplicación de escritorio, cargador web y cualquier cliente de terceros que quieras crear.
El flujo de subida tiene tres pasos:
- Inicio — indícanos que quieres subir un archivo. Te devolvemos una o más URLs prefirmadas que apuntan a Cloudflare R2.
- Subir a R2 —
PUTtus bytes directamente a la(s) URL(s) prefirmada(s). Los bytes no pasan por nuestros servidores. - Confirmar — indícanos que la subida terminó. Creamos un registro
Filey te entregamos una URL para compartir.
URL base
https://storage.to/api
Todos los endpoints a continuación son relativos a esta base. Ejemplo: POST /upload/init significa POST https://storage.to/api/upload/init.
Autenticación
La mayoría de los endpoints no requieren autenticación. Las subidas anónimas son una función principal.
La autenticación es opcional y desbloquea:
- Subidas vinculadas a tu cuenta (visibles en /dashboard)
- Funciones premium (archivos permanentes, mayor almacenamiento)
- Mutaciones basadas en propiedad (eliminar, establecer contraseña, cambiar expiración) sin necesidad de que el token de visitante coincida
Usamos tokens bearer Laravel Sanctum. Genera un token mediante el paso OAuth en escritorio o el inicio de sesión web, luego envíalo como:
Authorization: Bearer <token>
Token de visitante
Los clientes anónimos necesitan una forma de probar la propiedad de sus subidas sin una cuenta. Usamos un token de visitante — una cadena aleatoria que el cliente genera una vez y reutiliza. Envíalo con cada solicitud:
X-Visitor-Token: <random-string>
En la web, el token se almacena automáticamente en la cookie visitor_token. El CLI lo guarda en ~/.config/storageto/token (ver Documentación CLI).
Para endpoints de mutación (eliminar, establecer contraseña, cambiar expiración), la propiedad se confirma si o el token de visitante coincide o la solicitud proviene de la misma IP que creó el archivo.
Errores
Los errores siguen un formato consistente:
{
"success": false,
"error": "Human-readable message"
}
Códigos de estado HTTP comunes:
| Código | Significado |
|---|---|
200 | OK. |
201 | Creado. |
400 | Solicitud incorrecta (p. ej. límite de tamaño de colección excedido). |
401 | Contraseña requerida o incorrecta. |
403 | No autorizado (no es el propietario del recurso). |
404 | Recurso no encontrado o expirado. |
422 | Validación fallida o restricción de plan/cupo. |
429 | Límite de tasa o cuota de subida alcanzada. |
500 | Error del servidor. Revisa estado. |
Límites de velocidad
Todos los límites de velocidad son por IP. Una respuesta 429 incluye los encabezados estándar Retry-After, X-RateLimit-Limit y X-RateLimit-Remaining.
| Ámbito | Límite |
|---|---|
| Inicio / confirmación / aborto de subida | 60 / minuto |
| Finalización multipartes | 500 / minuto |
| URLs de partes multipartes | 120 / minuto |
| Inicio / confirmación por lotes | 500 / minuto |
| Consultas de estado (archivo y colección) | 120 / minuto |
| Configuración (contraseña, expiración, descargas máximas) | 30 / minuto |
| Verificación de contraseña | 10 / minuto |
| Crear colección | 30 / minuto |
| Gestionar (listo, eliminar) | 60 / minuto |
| Subida de miniatura | 120 / minuto |
| Subida ShareX | 20 / día |
| Analíticas / errores de la app | 120 y 60 / minuto |
Cuota de subida: Los clientes anónimos tienen dos límites en paralelo — 100 GB / 24 h por token de visitante e 500 GB / 24 h por IP (el límite de IP captura tráfico sin token y redes compartidas). Cuando se excede cualquiera, recibirás un 429 con detalles. Esto es solo una cuota subir — las descargas son ilimitadas y sin restricciones (servidas directamente desde URLs firmadas de R2).
Subir
El flujo de subida en tres pasos para cualquier archivo, incluidos archivos de más de 5 GB (automáticamente multipartes). Si solo necesitas una subida rápida tipo captura de pantalla, usa ShareX en su lugar.
/upload/init
60/min
Inicia una subida. Para archivos >50 MB la respuesta incluye part_urls para una subida multiparte; de lo contrario, una sola url.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
filename | string · required | Nombre de archivo original. Máx. 255 caracteres. |
content_type | string · required | Tipo MIME. |
size | integer · required | Tamaño del archivo en bytes. Mín. 1. |
/upload/parts
120/min
Solicita URLs adicionales para partes de una subida multiparte en curso. Se usa cuando /init devolvió menos URLs que partes tienes (o expiraron).
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
upload_id | string · required | El upload_id de /init. |
part_numbers | array<int> · required | Números de partes para obtener URLs. |
/upload/complete-multipart
500/min
Finaliza una subida multiparte en R2 una vez que todas las partes están subidas.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
upload_id | string · required | El upload_id de /init. |
parts | array · required | Cada entrada: { partNumber, etag } de la respuesta de R2. |
/upload/abort
60/min
Cancela una subida multiparte y elimina cualquier dato parcial en R2.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
upload_id | string · required | La subida a cancelar. |
/upload/confirm
60/min
Confirma que la subida está completa. Aquí creamos el registro File y devolvemos la URL para compartir.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
filename | string · required | Nombre de archivo original. |
size | integer · required | Tamaño del archivo en bytes. |
content_type | string · required | Tipo MIME. |
r2_key | string · required | El r2_key de /init. |
collection_id | string · optional | Adjuntar a una colección. |
crc32 | integer · optional | Checksum CRC32 para verificación de integridad. |
file_id | string(9) · optional | Completa un ID de archivo reservado previamente reservado. |
/file/reserve
60/min
Reserva un ID de archivo y una URL para compartir antes de que los bytes estén listos. Útil cuando necesitas entregar un enlace primero y completar la subida después. La propiedad está ligada a tu token de visitante + IP. Finaliza la subida más tarde con /upload/init + /upload/confirm, pasando file_id para confirmar.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
filename | string · optional | Nombre de archivo de marcador. Por defecto "Pending". |
content_type | string · optional | Tipo MIME de marcador. |
/upload/init-batch
500/min
Equivalente por lotes de /upload/init, optimizado para el cargador web. Inicia hasta 250 archivos en un solo viaje de ida y vuelta.
Usado internamente por el cargador web. La mayoría de los clientes deberían preferir /upload/init para un solo archivo.
/upload/confirm-batch
500/min
Equivalente por lotes de /upload/confirm. Confirma muchos archivos en un solo viaje de ida y vuelta.
Colecciones
Una colección agrupa múltiples archivos bajo una única URL para compartir (/c/{id}). Hasta 10,000 archivos y 25 GB en total.
/collection
30/min
Crea una nueva colección. Adjunta archivos después pasando collection_id en /upload/confirm.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
expected_file_count | integer · optional | Sugerencia para marcar automáticamente la colección como lista una vez que todos los archivos esperados hayan sido confirmados. |
/collection/{id}/status
120/min
Consulta el estado de una colección. También marca automáticamente la colección como lista si todos los archivos esperados han sido confirmados.
/collection/{id}/ready
Owner only
60/min
Marca la colección como lista para descargar. Normalmente no es necesario — las colecciones se marcan automáticamente como listas una vez que se alcanza expected_file_count.
/collection/{id}
Owner only
60/min
Elimina una colección y todos sus archivos.
/collection/{id}/password
Owner only
30/min
Establece una contraseña en la colección. Requiere entre 4 y 100 caracteres.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
password | string · required | 4–100 caracteres. |
/collection/{id}/password
Owner only
30/min
Elimina la contraseña de una colección.
/collection/{id}/verify-password
10/min
Verifica una contraseña. Devuelve 200 si es correcta, 401 si es incorrecta.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
password | string · required |
/collection/{id}/expiry
Owner only
30/min
Cambiar la expiración de una colección.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
days | integer · optional | De 1 a 7 días a partir de ahora. Omite o usa null para permanente (solo premium). |
/collection/{id}/max-downloads
Owner only
30/min
Establece un límite de descargas (elimina después de N descargas). La colección se elimina automáticamente al alcanzarlo.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
max_downloads | integer · optional | De 1 a 1000. Debe superar el conteo actual de descargas. null para eliminar el límite. |
Archivos
Todas las configuraciones a nivel de archivo (contraseña, expiración, descargas máximas) reflejan los endpoints de la colección. Solo para el propietario.
/file/{id}/status
120/min
Verifica si un archivo aún está pendiente de subir.
/file/{id}
Owner only
60/min
Elimina un archivo inmediatamente.
/file/{id}/thumbnail
Owner only
120/min
Sube una imagen en miniatura para un video o archivo de imagen (usada en la página de descarga). Máximo 2 MB.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
thumbnail | image · required | Carga multipart. Máximo 2 MB. |
/file/{id}/password
Owner only
30/min
Establece una contraseña en un archivo. Requiere entre 4 y 100 caracteres.
/file/{id}/password
Owner only
30/min
Eliminar la contraseña de un archivo.
/file/{id}/verify-password
10/min
Verificar la contraseña de un archivo.
/file/{id}/expiry
Owner only
30/min
Cambiar la expiración de un archivo.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
days | integer · optional | De 1 a 7 días a partir de ahora. Omite o usa null para permanente (solo premium). |
/file/{id}/max-downloads
Owner only
30/min
Limitar el total de descargas de un archivo. Se elimina automáticamente al alcanzarlo.
Subida ShareX
Punto de subida única — envía un archivo multipart, recibe una URL para compartir. Sin pasos de inicio/confirmación. Ideal para herramientas de captura de pantalla. Guía completa de configuración en /es/docs/sharex.
Autenticación de escritorio
Para clientes autenticados (p. ej., la app de escritorio) que tengan un token Sanctum.
/user
Bearer token
Devuelve el usuario autenticado.
/auth/logout
Bearer token
Revoca el token de acceso actual.
Misceláneo
/health
Chequeo de estado. Hace ping a la base de datos, almacenamiento R2 y caché Redis. Devuelve 200 si todo está bien, 503 de lo contrario.
/activity
Transmisión en vivo de actividad para el globo de la página principal. Cacheado en el edge de Cloudflare.
/bandwidth/status
60/min
Uso actual de cuota de subida para el solicitante — usado por la CLI y la app de escritorio para mostrar capacidad restante. La forma de la respuesta varía para usuarios autenticados. A pesar del nombre de la URL, esto solo rastrea bytes subir; las descargas no se cuentan.
/app-analytics
120/min
Envía un evento de uso desde la CLI o la app de escritorio.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
app | string · required | desktop, cli o web. |
version | string · optional | Versión del cliente. |
event | string · required | Nombre del evento, p. ej. upload_complete. |
context | object · optional | Metadatos adicionales. |
/app-errors
60/min
Envía un informe de error desde la CLI o la app de escritorio. Deducción de duplicados en el servidor — máximo 10 del mismo error por hora.
Cuerpo de la solicitud
| Campo | Tipo | Descripción |
|---|---|---|
app | string · required | desktop, cli o web. |
type | string · required | Clase/tipo de error. |
message | string · required | Mensaje de error. |
stack | string · optional | Traza de pila. |
version, os, os_version, arch, context | various · optional | Metadatos de diagnóstico. |