Skip to content

上传 API

上传 API 支持通过第三方上传文件至 CloudFlare ImgBed,便于集成到各种应用和服务中。

基本信息

  • 端点/upload
  • 方法POST
  • 认证:上传认证码或 API Token(需要 upload 权限)
  • 内容类型multipart/form-data

响应格式

json
[{ "src": "/file/abc123_image.jpg" }]

src 不包含域名,需自行拼接。使用 returnFormat=full 可返回完整链接。

普通上传

直接通过 /upload 端点上传文件,适用于小文件。

参数

Query 参数:

参数名类型必需默认值说明
authCodestring-上传认证码
uploadChannelstringtelegram上传渠道:telegramcfr2s3discordhuggingfacewebdav
channelNamestring-指定渠道名称(多渠道场景),可通过 /api/channels 获取可用列表
serverCompressbooleantrue服务端压缩(仅 Telegram 渠道图片)
autoRetrybooleantrue失败时自动切换渠道重试
uploadNameTypestringdefault命名方式:default(前缀_原名)、index(仅前缀)、origin(仅原名)、short(短链接)
returnFormatstringdefault返回格式:default/file/id)、full(完整链接)
uploadFolderstring-上传目录,相对路径,如 img/test

Body 参数(FormData):

参数名类型必需说明
fileFile要上传的文件

示例

bash
curl -X POST 'https://your.domain/upload?authCode=YOUR_CODE&uploadChannel=telegram' \
  -F 'file=@"/path/to/image.jpg"'

文件大小限制

  • Cloudflare Pages 部署:单次请求体上限 100MB
  • Telegram 渠道:单文件上限 20MB(超过自动服务端分片)
  • Discord 渠道:免费 10MB / Nitro 25MB
  • HuggingFace 渠道:普通上传走后端代理,受 CF Workers CPU 时间限制,建议大文件使用直传方式(见下文)

分块上传(Telegram / R2 / S3 / Discord)

当文件较大时,客户端可将文件切分为多个分块,逐块上传后由服务端合并。适用于 telegramcfr2s3discord 四个渠道。

HuggingFace 渠道不支持分块上传

HuggingFace 渠道有独立的大文件直传流程,请参考下方 HuggingFace 大文件直传 章节。

推荐分块大小

渠道推荐分块大小说明
telegram16MBTelegram Bot getFile 下载限制 20MB,留 4MB 安全余量
cfr2 / s35MB - 20MB遵循 S3 Multipart Upload 规范,最小 5MB
discord8MB免费用户 10MB 限制,留余量

上传流程

分块上传分为三步:初始化 → 逐块上传 → 合并

第一步:初始化

创建上传会话,获取 uploadId

Query 参数:

参数名类型必需说明
authCodestring上传认证码
initChunkedboolean固定为 true
uploadChannelstring上传渠道:telegramcfr2s3discord
channelNamestring指定渠道名称(多渠道场景),可通过 /api/channels 获取可用列表

Body 参数(FormData):

参数名类型必需说明
originalFileNamestring原始文件名
originalFileTypestring原始文件 MIME 类型
totalChunksinteger分块总数

请求示例:

POST /upload?authCode=YOUR_CODE&initChunked=true&uploadChannel=telegram
Content-Type: multipart/form-data

FormData:
  originalFileName: "video.mp4"
  originalFileType: "video/mp4"
  totalChunks: 5

响应示例:

json
{
  "success": true,
  "uploadId": "upload_1713500000000_abc123def",
  "sessionInfo": {
    "uploadId": "upload_1713500000000_abc123def",
    "originalFileName": "video.mp4",
    "totalChunks": 5,
    "uploadChannel": "telegram"
  }
}

第二步:逐块上传

将文件按推荐大小切分,依次上传每个分块。每个请求是同步的,服务端会等待分块上传到存储端后才响应。

Query 参数:

参数名类型必需说明
authCodestring上传认证码
chunkedboolean固定为 true
uploadChannelstring上传渠道:telegramcfr2s3discord
channelNamestring指定渠道名称(多渠道场景),可通过 /api/channels 获取可用列表

Body 参数(FormData):

参数名类型必需说明
fileFile分块二进制数据
uploadIdstring初始化返回的上传会话 ID
chunkIndexinteger分块索引,从 0 开始
totalChunksinteger分块总数
originalFileNamestring原始文件名
originalFileTypestring原始文件 MIME 类型

请求示例:

POST /upload?authCode=YOUR_CODE&chunked=true&uploadChannel=telegram
Content-Type: multipart/form-data

FormData:
  file: <分块二进制数据>
  uploadId: "upload_1713500000000_abc123def"
  chunkIndex: 0
  totalChunks: 5
  originalFileName: "video.mp4"
  originalFileType: "video/mp4"

响应示例:

json
{
  "success": true,
  "message": "Chunk 1/5 received and being uploaded",
  "uploadId": "upload_1713500000000_abc123def",
  "chunkIndex": 0
}

并发上传

各分块可并发上传以提升速度。对于 R2/S3 渠道,第一个分块(chunkIndex=0)会初始化 Multipart Upload,其他分块会自动等待初始化完成(最多等待 60 秒)。

第三步:合并

所有分块上传完成后,请求合并。合并过程是同步的。

Query 参数:

参数名类型必需说明
authCodestring上传认证码
chunkedboolean固定为 true
mergeboolean固定为 true
uploadChannelstring上传渠道:telegramcfr2s3discord
channelNamestring指定渠道名称(多渠道场景),可通过 /api/channels 获取可用列表
returnFormatstring返回格式:default/file/id)、full(完整链接)
uploadFolderstring上传目录,相对路径,如 img/test

Body 参数(FormData):

参数名类型必需说明
uploadIdstring上传会话 ID
totalChunksinteger分块总数
originalFileNamestring原始文件名
originalFileTypestring原始文件 MIME 类型

请求示例:

POST /upload?authCode=YOUR_CODE&chunked=true&merge=true&uploadChannel=telegram
Content-Type: multipart/form-data

FormData:
  uploadId: "upload_1713500000000_abc123def"
  totalChunks: 5
  originalFileName: "video.mp4"
  originalFileType: "video/mp4"

响应示例:

json
[{ "src": "/file/1713500000000_video.mp4" }]

失败重试

合并时服务端会自动检查各分块状态,对失败或超时的分块进行重试(最多 5 次)。如果仍有分块未完成,合并会返回错误。

清理请求

如果上传中途取消,可发送清理请求释放临时数据。

Query 参数:

参数名类型必需说明
authCodestring上传认证码
cleanupboolean固定为 true
uploadIdstring上传会话 ID
totalChunksinteger分块总数
POST /upload?authCode=YOUR_CODE&cleanup=true&uploadId=xxx&totalChunks=5

HuggingFace 大文件直传

HuggingFace 渠道采用独立的上传流程,文件由客户端直接上传到 HuggingFace LFS 存储,CF Workers 仅负责签名和提交,从而绕过 Cloudflare 的 100MB 请求体限制和 CPU 时间限制。

上传方式选择

场景方式说明
小文件(< 20MB)普通上传 /upload?uploadChannel=huggingface文件经由后端代理上传
大文件(≥ 20MB)直传流程(三步)客户端直传 HuggingFace S3,后端只做签名和提交

直传流程

前置准备

客户端需要预先计算:

  • SHA-256:文件完整内容的 SHA-256 哈希(hex 字符串)
  • fileSample:文件前 512 字节的 Base64 编码

第一步:获取上传 URL

请求参数(JSON Body):

参数名类型必需说明
fileNamestring文件名
fileTypestring文件 MIME 类型
fileSizeinteger文件大小(字节)
sha256string文件 SHA-256 哈希(hex)
fileSamplestring文件前 512 字节的 Base64
channelNamestring指定渠道名称(多渠道场景),可通过 /api/channels 获取可用列表
uploadNameTypestring命名方式:default(前缀_原名)、index(仅前缀)、origin(仅原名)、short(短链接)
uploadFolderstring上传目录,相对路径,如 img/test

请求示例:

POST /upload/huggingface/getUploadUrl
Content-Type: application/json
Authorization: Bearer <API_TOKEN>

{
  "fileName": "large-video.mp4",
  "fileType": "video/mp4",
  "fileSize": 524288000,
  "sha256": "e3b0c44298fc1c149afbf4c8996fb924...",
  "fileSample": "AAAAIGZ0eXBpc29t...",
  "channelName": "my-hf-channel",
  "uploadNameType": "default",
  "uploadFolder": "videos"
}

响应示例:

json
{
  "success": true,
  "fullId": "videos/1713500000000_large-video.mp4",
  "filePath": "videos/a1b2c3d4_1713500000000_large-video.mp4",
  "channelName": "my-hf-channel",
  "repo": "username/repo-name",
  "needsLfs": true,
  "alreadyExists": false,
  "oid": "e3b0c44298fc1c149afbf4c8996fb924...",
  "uploadAction": {
    "href": "https://s3.amazonaws.com/...",
    "header": { ... }
  }
}

关键字段说明:

  • needsLfs: false:文件无需 LFS(极小的文本文件),直接跳到第三步提交
  • alreadyExists: true:文件已存在于 LFS,跳过第二步直接提交
  • uploadAction.header.chunk_size:如果存在此字段,说明 HuggingFace 要求分片上传,header 中的零填充数字键("00001", "00002", ...)为各分片的预签名上传 URL

第二步:上传文件到 HuggingFace S3

根据 uploadAction 返回的信息,客户端直接上传到 HuggingFace 的 S3 存储。

基本上传(无 chunk_size):

PUT <uploadAction.href>
Headers: <uploadAction.header>
Body: <文件二进制内容>

分片上传(有 chunk_size):

将文件按 chunk_size 切分,依次 PUT 到 header["00001"]header["00002"] ... 对应的 URL,收集每个响应的 ETag。全部上传完成后,POST 到 uploadAction.href 完成合并:

POST <uploadAction.href>
Content-Type: application/vnd.git-lfs+json

{
  "oid": "<sha256>",
  "parts": [
    { "partNumber": 1, "etag": "\"abc123\"" },
    { "partNumber": 2, "etag": "\"def456\"" }
  ]
}

第三步:提交文件引用

上传完成后,调用提交接口将文件注册到系统数据库。

请求参数(JSON Body):

参数名类型必需说明
fullIdstring第一步返回的文件 ID
filePathstring第一步返回的存储路径
sha256string文件 SHA-256 哈希(hex)
fileSizeinteger文件大小(字节)
fileNamestring文件名
fileTypestring文件 MIME 类型
channelNamestring指定渠道名称(多渠道场景),可通过 /api/channels 获取可用列表

请求示例:

POST /upload/huggingface/commitUpload
Content-Type: application/json
Authorization: Bearer <API_TOKEN>

{
  "fullId": "videos/1713500000000_large-video.mp4",
  "filePath": "videos/a1b2c3d4_1713500000000_large-video.mp4",
  "sha256": "e3b0c44298fc1c149afbf4c8996fb924...",
  "fileSize": 524288000,
  "fileName": "large-video.mp4",
  "fileType": "video/mp4",
  "channelName": "my-hf-channel"
}

响应示例:

json
{
  "success": true,
  "src": "/file/videos/1713500000000_large-video.mp4",
  "fileUrl": "https://huggingface.co/datasets/username/repo-name/resolve/main/videos/a1b2c3d4_1713500000000_large-video.mp4",
  "fullId": "videos/1713500000000_large-video.mp4"
}

流程总结

HF直传示意图

基于 MIT 许可发布