REST API
通过 HTTP 上传文件、创建集合并管理分享。所有响应均为 JSON;匿名上传无需 API 密钥。
简介
storage.to API 为我们的 命令行界面(CLI)、桌面应用、网页上传器 以及你想构建的任何第三方客户端提供支持。
上传流程分为三步:
- 初始化 — 告诉我们你要上传一个文件。我们会返回一个或多个指向 Cloudflare R2 的预签名 URL。
- 上传到 R2 — :将你的字节直接上传到预签名 URL(或多个)。字节不会经过我们的服务器。
- 确认 — 告知我们上传已完成。我们将创建一个
File记录,并给你一个可分享的 URL。
基础 URL
https://storage.to/api
以下所有端点均相对于此基础路径。例如:POST /upload/init 表示 POST https://storage.to/api/upload/init。
身份验证
大多数接口不需要身份验证。 匿名上传是核心功能。
身份验证是可选的,可解锁:
- 上传内容会绑定到你的账户(可在 /dashboard 查看)
- 高级功能(永久文件、更大存储空间)
- 基于所有权的变更(删除、设置密码、更改过期时间),无需匹配 visitor-token
我们使用 Laravel Sanctum bearer tokens。通过桌面端 OAuth 交接或网页登录获取令牌,然后以如下方式发送:
Authorization: Bearer <token>
访客令牌
匿名客户端需要一种方式,在不拥有账户的情况下证明其对自身上传内容的所有权。我们使用 访客令牌——由客户端生成的一串随机字符串,只生成一次并重复使用。每次请求都要发送:
X-Visitor-Token: <random-string>
在网页端,令牌会自动存储在 visitor_token 这个 cookie 中。CLI 会将其存储在 ~/.config/storageto/token(见 CLI 文档)。
对于变更端点(删除、设置密码、更改到期时间),当满足 要么(访问者 token 匹配)或 或(请求来自创建该文件的同一 IP)时,即可确认所有权。两者都可能丢失(清除 Cookie、网络变更)。从现在开始,所有者 token 是首选的证明。
所有者令牌
每个创建资源的端点(/upload/init multipart、/upload/confirm、/upload/reserve、/collection)都会在响应中返回一个 owner_token。该 token 是与该特定资源绑定的、经过签名的所有权证明,不依赖你的 IP 或访问者 token。
将 token 与资源 ID 一起保存,并在任何变更请求中按以下方式发送:
Authorization: Owner <token>
或者,如果你已经在已认证的会话中使用 Authorization: Bearer,请按以下方式发送:
X-Owner-Token: <token>
服务器会将 owner token 作为有效的所有权证明,与旧版的 访客令牌 + IP 兜底机制一起接受——持有 token 的客户端在切换网络或清除 Cookie 后仍可继续工作,而不持有 token 的客户端则仍会像以前一样正常工作。
token 的有效期与资源一致:可以安全地长期保存,并且不会单独过期。token 丢失意味着你将失去对该资源(文件/集合/上传)的控制——请把它们当作本地密码来对待。
错误
错误遵循一致的格式:
{
"success": false,
"error": "Human-readable message"
}
常见的 HTTP 状态码:
| 代码 | 含义 |
|---|---|
200 | 成功。 |
201 | 已创建。 |
400 | 错误请求(例如:超出了集合大小限制)。 |
401 | 需要密码或密码不正确。 |
403 | 未授权(不是该资源的所有者)。 |
404 | 未找到资源或资源已过期。 |
422 | 校验失败,或触及套餐/配额限制。 |
429 | 触发了限流或上传配额限制。 |
500 | 服务器错误。请检查 状态。 |
速率限制
所有限流都按 IP 计算。429 响应会包含标准的 Retry-After、X-RateLimit-Limit 和 X-RateLimit-Remaining 请求头。
| 范围 | 限制 |
|---|---|
| 上传初始化 / 确认 / 取消 | 60 / 分钟 |
| 分片完成 | 500 / 分钟 |
| 分片部分的 URL | 120 / 分钟 |
| 批量初始化 / 确认 | 500 / 分钟 |
| 状态轮询(文件与集合) | 120 / 分钟 |
| 设置(密码、到期时间、最大下载次数) | 30 / 分钟 |
| 密码验证 | 10 / 分钟 |
| 创建集合 | 30 / 分钟 |
| 管理(就绪、删除) | 60 / 分钟 |
| 缩略图上传 | 120 / 分钟 |
| ShareX 上传 | 20 / 天 |
| 应用分析 / 错误 | 每分钟 120 和 60 |
上传配额: 匿名客户端有两个并行的上限——每 访客令牌 100 GB / 24 小时 和 每 IP 500 GB / 24 小时(IP 上限会捕获无令牌流量和共享网络)。当任一项超出时,你会收到带详细信息的 429。这是一个 上传 配额限制——下载不限制且不限速(直接由 R2 的签名 URL 提供)。
上传
任意文件的三步上传流程,包括超过 5 GB 的文件(会自动使用分片)。如果你只需要快速的截图风格上传,请改看 ShareX。
/upload/init
60/min
发起上传。对于大于 50 MB 的文件,响应为分片上传(type: "multipart" 字段);否则为单次预签名 PUT。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
filename | string · required | 原始文件名。最多 255 个字符。 |
content_type | string · required | MIME 类型。 |
size | integer · required | 以字节为单位的文件大小。最小 1。 |
/upload/parts
Owner only
120/min
为进行中的分片上传请求更多分片 URL。当 /init 返回的 URL 数量少于你拥有的分片数量(或这些 URL 已过期)时使用。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
upload_id | string · required | 来自 /init 的 upload_id。 |
part_numbers | array<int> · required | 要获取 URL 的分片编号。 |
/upload/complete-multipart
Owner only
500/min
当所有分片都上传完成后,在 R2 上完成分片上传。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
upload_id | string · required | 来自 /init 的 upload_id。 |
parts | array · required | 每一项:来自 R2 响应的 { partNumber, etag }。 |
/upload/abort
Owner only
60/min
取消分片上传,并清理 R2 上的任何部分数据。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
upload_id | string · required | 要中止的上传。 |
/upload/confirm
60/min
确认上传已完成。这时我们会创建 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。 |
/file/reserve
60/min
在字节数据准备好 之前 之前预留文件 ID 和可分享 URL。当你需要先发出链接,之后再完成上传时很有用。所有权绑定到你的访客 token + IP。稍后用 /upload/init + /upload/confirm 完成上传,并在确认时传入 file_id。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
filename | string · optional | 占位文件名。默认值为 "Pending"。 |
content_type | string · optional | 占位 MIME 类型。 |
/upload/init-batch
500/min
/upload/init 的批量等价接口,针对网页上传器进行了优化。一轮请求最多启动 250 个文件。
供网页上传器内部使用。大多数客户端应优先使用单文件的 /upload/init。
/upload/confirm-batch
500/min
/upload/confirm 的批量等价接口。一轮请求确认多个文件。
集合
集合会把多个文件归到同一个分享 URL(/c/{id})下。最多 10,000 个文件,总计 25 GB。
/collection
30/min
创建一个新的集合。之后通过在 /upload/confirm 上传入 collection_id 来附加文件。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
expected_file_count | integer · optional | 当所有预期文件都已确认后,用于自动标记集合为就绪的提示。 |
/collection/{id}/status
120/min
轮询集合的状态。如果所有预期文件都已确认,也会自动将集合标记为就绪。
/collection/{id}/ready
Owner only
60/min
将集合标记为可下载。通常不需要——一旦达到 expected_file_count,集合会自动变为就绪。
/collection/{id}
Owner only
60/min
删除集合及其所有文件。
/collection/{id}/password
Owner only
30/min
为集合设置密码。需要 4–100 个字符。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
password | string · required | 4–100 个字符。 |
/collection/{id}/password
Owner only
30/min
移除集合的密码。
/collection/{id}/verify-password
10/min
校验密码。成功返回 200,密码错误返回 401。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
password | string · required |
/collection/{id}/expiry
Owner only
30/min
更改集合的过期时间。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
days | integer · optional | 从现在起 1–7 天。省略或使用 null 表示永久有效(仅高级版)。 |
/collection/{id}/max-downloads
Owner only
30/min
设置下载上限(burn-after-N-downloads)。达到上限后集合会自动删除。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
max_downloads | integer · optional | 1–1000。必须大于当前下载次数。使用 null 可移除上限。 |
文件
所有文件级设置(密码、过期时间、最大下载次数)与集合端点一致。仅所有者可用。
/file/{id}/status
120/min
检查文件是否仍在等待上传。
/file/{id}
Owner only
60/min
立即删除文件。
/file/{id}/thumbnail
Owner only
120/min
为视频或图片文件上传缩略图(用于下载页面)。最大 2 MB。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
thumbnail | image · required | 分片上传。最大 2 MB。 |
/file/{id}/password
Owner only
30/min
为文件设置密码。需要 4–100 个字符。
/file/{id}/password
Owner only
30/min
移除文件密码。
/file/{id}/verify-password
10/min
验证文件密码。
/file/{id}/expiry
Owner only
30/min
更改文件的过期时间。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
days | integer · optional | 从现在起 1–7 天。省略或使用 null 表示永久有效(仅高级版)。 |
/file/{id}/max-downloads
Owner only
30/min
限制文件的总下载次数;达到上限后将自动删除。
ShareX 上传
一次性上传端点——发送分片文件,返回可分享的 URL。不需要 init/confirm 的流程。适合截图工具。完整设置指南见 /zh/docs/sharex。
桌面端认证
用于持有 Sanctum token 的已认证客户端(例如桌面应用)。
/user
Bearer token
返回已认证的用户。
/auth/logout
Bearer token
撤销当前访问令牌。
杂项
/health
健康检查。会 ping 数据库、R2 存储和 Redis 缓存;如果全部正常返回 200,否则返回 503。
/activity
主页地球仪的实时活动流;已在 Cloudflare 边缘缓存。
/bandwidth/status
60/min
调用方当前的上传配额使用量——供 CLI 和桌面应用展示剩余容量。对已认证用户,返回结构会有所不同。尽管 URL 名称如此,这里只统计 上传 字节数;下载不计入。
/app-analytics
120/min
从 CLI 或桌面应用提交一次使用事件。
请求体
| 字段 | 类型 | 描述 |
|---|---|---|
app | string · required | desktop、cli 或 web。 |
version | string · optional | 客户端版本。 |
event | string · required | 事件名称,例如 upload_complete。 |
context | object · optional | 额外的元数据。 |
/app-errors
60/min
从 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 | 诊断元数据。 |