REST API

cpcp 的 HTTP 接口和网页共用同一条链路:匿名可用、有限流、包裹 1 小时后失效。做 Agent 集成优先用 MCP;需要完全控制请求时用 REST。

先看边界

  • 文字最多 64KB;单个文件最多 100MB;每个包裹最多 20 个文件、合计 200MB。
  • 包裹 1 小时后过期,最多成功取件 10 次;不需要账号。MCP token 在 /zh/keys 自助生成。
  • 接口按 IP 限流;脚本要处理 429 并做退避,不要并发重试。
  • 除上传外,请求和响应都是 JSON;错误统一为 { error, message? }。

端点

方法路径作用成功响应
GET/api/ping健康检查{ ok: true }
POST/api/parcel/text寄一个文字包裹{ code, url, expiresAt }
POST/api/parcel/file/init声明一个待上传文件{ fileId }
PUT/api/parcel/file/:fileId上传原始字节{ ok: true }
POST/api/parcel/seal把文件封成一个包裹{ code, url, expiresAt }
GET/api/parcel/:code取件,并消耗一次取件次数{ kind, text?, files?, expiresAt, remainingClaims }
GET/d/:fileId/:token下载单个文件文件流(attachment)

寄一个文字包裹

请求体:{"content":"hello"},也可以带 ttl(秒,默认 3600)。

curl -s https://<this-site>/api/parcel/text -H 'content-type: application/json' -d '{"content":"hello"}'

返回:{"code":"123456","url":"https://<this-site>/p/123456","expiresAt":1760000000000}。把 code 或 url 交给收件人。

寄一个文件

上传的字节数必须和 init 声明的 size 完全一致,否则返回 400 bad_request;上传成功后重复 PUT 返回 404 no_init,不会覆盖已上传内容。

取件返回 kind 为 file 时,files 数组里每一项包含 name、size 和 downloadUrl。downloadUrl 是带签名的相对路径,只能配合本站域名使用,并随包裹一起过期。

  1. 声明文件 POST /api/parcel/file/init,请求体 {name, size, mime},拿到 fileId。size 必须等于实际字节数。
  2. 上传字节 PUT /api/parcel/file/<fileId>,body 是原始字节流。curl -X PUT --data-binary @note.txt -H 'content-type: application/octet-stream'。
  3. 封箱 POST /api/parcel/seal,请求体 {fileIds:[...]},拿到 6 位取件码。多文件时一次传入全部 fileId。

错误码

HTTPerror什么时候出现
400bad_requestJSON 不合法、字段缺失,或上传字节数与声明不符
400too_large文字超过 64KB、单文件超过 100MB,或包裹超过 20 件 / 200MB
404not_found取件码不存在或已用完(与输错码同一句话)
404no_initPUT 的文件不存在、已上传,或不属于待封箱状态
404unknown_file封箱时 fileId 不存在,或对应的存储对象不存在
409already_sealed文件已经属于另一个包裹
410expired取件码存在但已过期(只在 10 分钟宽限窗口内)
429rate_limited超过按 IP 的限流;等待后重试
429turnstile_required同一 IP 多次取件失败;带上 Turnstile token 重试
503busy全站配额或取件码池暂时耗尽;稍后重试

相关

回首页寄件