REST API
通过 HTTP 上传文件、创建集合并管理分享。所有响应均为 JSON;匿名上传无需 API 密钥。
上传的工作原理
storage.to API 为我们的 命令行界面(CLI)、桌面应用、网页上传器 以及你想构建的任何第三方客户端提供支持。 上传流程分为三步:
PUT 将你的字节直接上传到预签名 URL(或多个)。字节不会经过我们的服务器。File 记录,并给你一个可分享的 URL。以下所有端点均相对于此基础路径。例如:POST /upload/init 表示 POST https://storage.to/api/upload/init。
身份验证
匿名上传无需身份验证即可使用,但限制较严。 无密钥调用每台设备或IP在滚动24小时内最多50个文件,另受下方带宽配额限制,文件3天后过期。
使用免费账户认证可解锁:
- 无每日文件数上限
- 无上传带宽配额
- 上传内容会绑定到你的账户(可在 /dashboard 查看)
- 高级功能(永久文件、更大存储空间)
- 基于所有权的变更(删除、设置密码、更改过期时间),无需匹配 visitor-token
限制一览
expiry_days 最长 7 天expiry_days 最长 7 天没有月度配额:所有限制都是滚动 24 小时窗口或每分钟速率限制。 免费套餐没有固定的存储空间:每个文件都会自行过期,因此不会累积占用配额。
证明所有权
/upload/init multipart、/upload/confirm、/file/reserve、/collection)都会在响应中返回一个 owner_token。该 token 是与该特定资源绑定的、经过签名的所有权证明,不依赖你的 IP 或访问者 token。 令牌的生命周期与资源一致:可以安全保存,不会独立过期。丢失令牌就意味着失去对该资源(文件/集合/上传)的控制——请把它们当作本地密码来对待。# 或者,与 Bearer 会话一起使用
X-Owner-Token: <token>
visitor_token 这个 cookie 中。CLI 会将其存储在 ~/.config/storageto/token(见 CLI 文档)。对于变更端点(删除、设置密码、更改到期时间),当满足 要么(访问者 token 匹配)或 或(请求来自创建该文件的同一 IP)时,即可确认所有权。两者都可能丢失(清除 Cookie、网络变更)。从现在开始,所有者 token 是首选的证明。
错误
错误遵循一致的格式: { "success": false, "error": "…" }
速率限制
所有限流都按 IP 计算。429 响应会包含标准的 Retry-After、X-RateLimit-Limit 和 X-RateLimit-Remaining 请求头。
上传配额: 匿名客户端并行有两个上限--每 访客令牌 100 GB / 24 小时 和 每 IP 500 GB / 24 小时(IP 上限用于捕获无令牌流量以及共享网络)。当任一上限超出,你会收到带详细信息的 429。这只是 上传 配额--下载无限制且不限速。
上传
8 个端点任意文件的三步上传流程,包括超过 5 GB 的文件(会自动使用分片)。如果你只需要快速的截图风格上传,请改看 ShareX。
发起上传。对于大于 50 MB 的文件,响应为分片上传(type: "multipart" 字段);否则为单次预签名 PUT。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
filename | string · required | 原始文件名。最多 255 个字符。 |
content_type | string · required | MIME 类型。 |
size | integer · required | 以字节为单位的文件大小。最小 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_..." }
为进行中的分片上传请求更多分片 URL。当 /init 返回的 URL 数量少于你拥有的分片数量(或这些 URL 已过期)时使用。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
upload_id | string · required | 来自 /init 的 upload_id。 |
part_numbers | array<int> · required | 要获取 URL 的分片编号。 |
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://..." } ] }
当所有分片都上传完成后,完成分片上传。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
upload_id | string · required | 来自 /init 的 upload_id。 |
parts | array · required | 每一项:来自 分片上传响应的 { partNumber, etag }。 |
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 }
取消分片上传,并清理 任何部分数据。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
upload_id | string · required | 要中止的上传。 |
curl -X POST https://storage.to/api/upload/abort \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ..." }'
确认上传已完成。这时我们会创建 File 记录,并返回可分享的 URL。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
filename | string · required | 原始文件名。 |
size | integer · required | 以字节为单位的文件大小。 |
content_type | string · required | MIME 类型。 |
r2_key | string · required | 来自 /init 的 r2_key。 |
collection_id | string · optional | 添加到集合。 |
crc32 | integer · optional | 用于完整性校验的 CRC32 校验和。 |
file_id | string(9) · optional | 完成先前的 预留 文件 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_..." }
在字节数据准备好 之前 之前预留文件 ID 和可分享 URL。当你需要先发出链接,之后再完成上传时很有用。所有权绑定到你的访客 token + IP。稍后用 /upload/init + /upload/confirm 完成上传,并在确认时传入 file_id。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
filename | string · optional | 占位文件名。默认值为 "Pending"。 |
content_type | string · optional | 占位 MIME 类型。 |
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_..." }
/upload/init 的批量等价接口,针对网页上传器进行了优化。一轮请求最多启动 250 个文件。
供网页上传器内部使用。大多数客户端应优先使用单文件的 /upload/init。
/upload/confirm 的批量等价接口。一轮请求确认多个文件。
集合
9 个端点集合会把多个文件归到同一个分享 URL(/c/{id})下。最多 10,000 个文件,总计 25 GB。
创建一个新的集合。之后通过在 /upload/confirm 上传入 collection_id 来附加文件。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
expected_file_count | integer · optional | 当所有预期文件都已确认后,用于自动标记集合为就绪的提示。 |
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_..." }
轮询集合的状态。如果所有预期文件都已确认,也会自动将集合标记为就绪。
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" }
将集合标记为可下载。通常不需要——一旦达到 expected_file_count,集合会自动变为可下载状态。
删除集合及其所有文件。
为集合设置密码。需要 4–100 个字符。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
password | string · required | 4–100 个字符。 |
curl -X POST https://storage.to/api/collection/ABC123xyz/password \ -H "X-Visitor-Token: abc123" \ -d '{ "password": "hunter22" }'
移除集合的密码。
校验密码。成功返回 200,密码错误返回 401。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
password | string · required |
更改集合的过期时间。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
days | integer · optional | 从现在起 1–7 天,但不会晚于上传后 7 天(若当前到期时间更晚,则以其为准)。省略或设为 null 表示永久(仅限高级版)。 |
设置下载上限(burn-after-N-downloads)。达到上限后集合会自动删除。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
max_downloads | integer · optional | 1–1000。必须大于当前下载次数。使用 null 可移除上限。 |
文件
8 个端点所有文件级设置(密码、过期时间、最大下载次数)与集合端点一致。仅所有者可用。
检查文件是否仍在等待上传。
{ "pending": false }
立即删除文件。
为视频或图片文件上传缩略图(用于下载页面)。最大 2 MB。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
thumbnail | image · required | 分片上传。最大 2 MB。 |
{ "success": true, "thumbnail_url": "https://..." }
为文件设置密码。需要 4–100 个字符。
移除文件密码。
验证文件密码。
更改文件的过期时间。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
days | integer · optional | 从现在起 1–7 天,但不会晚于上传后 7 天(若当前到期时间更晚,则以其为准)。省略或设为 null 表示永久(仅限高级版)。 |
限制文件的总下载次数;达到上限后将自动删除。
桌面端认证
2 个端点适用于持有 Bearer 令牌的已登录客户端,例如桌面应用。
返回已认证的用户。
curl https://storage.to/api/user \ -H "Authorization: Bearer <token>"
{ "id": 42, "name": "Ada", "email": "ada@example.com", "is_premium": true }
撤销当前访问令牌。
杂项
5 个端点健康状态、配额和客户端遥测。
存活检查。当 API worker 正常服务时返回 200 和 { "status": "ok" }。
{ "status": "ok" }
主页地球仪的实时活动流;已在边缘缓存。
调用方当前的上传配额使用情况——供 CLI 和桌面应用展示剩余容量。对已认证用户,返回结构会有所不同。尽管 URL 名称如此,它只统计 上传 字节;下载不计入。
{ "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" }
从 CLI 或桌面应用提交一次使用事件。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
app | string · required | desktop、cli 或 web。 |
version | string · optional | 客户端版本。 |
event | string · required | 事件名称,例如 upload_complete。 |
context | object · optional | 额外的元数据。 |
通过 CLI 或桌面应用提交错误报告。服务器端去重——每小时同一错误最多 10 次。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
app | string · required | desktop、cli 或 web。 |
type | string · required | 错误类别/类型。 |
message | string · required | 错误信息。 |
stack | string · optional | 堆栈跟踪。 |
version, os, os_version, arch, context | various · optional | 诊断元数据。 |