POST/v1/uploads/{upload_id}/complete
完成上传
complete_upload
收到所有分段后,Sursa 会组装文件,将整个文件的 SHA-256 与请求体中的 sha256 进行比较,并执行与单次请求上传相同的检查:按内容签名检查格式,以及病毒扫描。结果为 ready,或带有 reject_reason 的 rejected(checksum_mismatch、type_mismatch、unsupported_format、infected、scan_unavailable、unsafe_content)。格式检查或病毒扫描导致的每次拒绝都以 file.rejected 写入审计日志。
200 响应表示结果已就绪;202 表示文件仍在检查中(processing),结果通过 GET /v1/uploads/{upload_id} 获取。如果状态变回 pending(API 实例重启中断了检查),请再次发送 complete。得到结果后重复 complete 会返回相同的结果。缺少分段时返回 409 uploads.incomplete(details.missing)。sha256 与创建时声明的值不同,或 parts[].etag 与已收到的分段不同时,返回 422 uploads.checksum_mismatch。已就绪但未被使用的上传保留 24 小时。在 1.62.0 中新增。
身份验证
在 Authorization 请求头中传入 API 密钥:Authorization: Bearer <密钥>。
路径参数
upload_idstring必填上传 ID(
upl_后跟 32 个十六进制字符)。length ≤ 64
请求头参数
Idempotency-Keystring写操作安全重试所用的键:1 到 255 个可打印 ASCII 字符;建议每个逻辑操作使用一个 UUID v4。24 小时内使用同一个键重试不会再次执行操作,而是返回已保存的响应(状态、响应头和正文),并附带
Idempotency-Replayed: true头。同一个键配合不同的方法、路径、Content-Type或正文时返回409 api.idempotency_mismatch;第一个请求仍在执行时返回409 api.idempotency_in_progress,并附带Retry-After: 1。收到 5xx 或 429 响应后,该键被释放,重试会再次执行操作。键的作用范围是组织和调用方(API 密钥、用户或自定义数据源密钥)。length ≥ 1, length ≤ 255
请求体
application/json
sha256string必填整个文件的 SHA-256。
partsarray of UploadPartRef可选的分段检查:每个分段的 ETag,即
PUT …/parts/{n}返回的值。items ≤ 1000
响应
200结果已就绪:`ready` 或 `rejected`。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
Idempotency-Replayed为
true时表示该响应是按此Idempotency-Key从已保存的响应重放的:操作没有再次执行。
application/json
idstring必填上传 ID(
upl_后跟 32 个十六进制字符)。filenamestring必填文件名(不含文件夹)。
content_typestring必填声明的内容类型;未声明时为空。
sizeinteger (int64)必填文件大小(字节)。
sha256string | null必填文件的 SHA-256,在创建时或调用
complete时声明;尚不知道时为null。part_sizeinteger (int64)必填除最后一个分段外,每个分段的大小(5 到 100 MiB)。
part_countinteger必填分段数量。
≥ 1, ≤ 1000
parts_receivedinteger必填已接收的分段数量。
≥ 0
按编号列出的已接收分段(在
POST /v1/uploads响应中为空)。reject_reasonstring | null必填拒绝原因(
rejected):checksum_mismatch、type_mismatch、unsupported_format、infected、scan_unavailable、unsafe_content。该枚举可能扩充;未被拒绝时为null。reject_detailsobject | null必填拒绝的详细信息(扩展名、声明的格式和检测到的格式、校验和);未被拒绝时为
null。created_atstring (date-time)必填上传的创建时间。
expires_atstring (date-time)必填完成上传的截止时间,以及上传就绪后使用它的截止时间。
completed_atstring (date-time) | null必填检查完成的时间(
ready或rejected)。consumed_atstring (date-time) | null必填上传被使用的时间(被卡片、压缩包或导入使用)。
202文件仍在检查中(`processing`)。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
Idempotency-Replayed为
true时表示该响应是按此Idempotency-Key从已保存的响应重放的:操作没有再次执行。
application/json
idstring必填上传 ID(
upl_后跟 32 个十六进制字符)。filenamestring必填文件名(不含文件夹)。
content_typestring必填声明的内容类型;未声明时为空。
sizeinteger (int64)必填文件大小(字节)。
sha256string | null必填文件的 SHA-256,在创建时或调用
complete时声明;尚不知道时为null。part_sizeinteger (int64)必填除最后一个分段外,每个分段的大小(5 到 100 MiB)。
part_countinteger必填分段数量。
≥ 1, ≤ 1000
parts_receivedinteger必填已接收的分段数量。
≥ 0
按编号列出的已接收分段(在
POST /v1/uploads响应中为空)。reject_reasonstring | null必填拒绝原因(
rejected):checksum_mismatch、type_mismatch、unsupported_format、infected、scan_unavailable、unsafe_content。该枚举可能扩充;未被拒绝时为null。reject_detailsobject | null必填拒绝的详细信息(扩展名、声明的格式和检测到的格式、校验和);未被拒绝时为
null。created_atstring (date-time)必填上传的创建时间。
expires_atstring (date-time)必填完成上传的截止时间,以及上传就绪后使用它的截止时间。
completed_atstring (date-time) | null必填检查完成的时间(
ready或rejected)。consumed_atstring (date-time) | null必填上传被使用的时间(被卡片、压缩包或导入使用)。
401未发送凭据(既没有会话 Cookie,也没有 API 密钥),或未找到该密钥。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
application/json
403不允许执行该操作:角色权限不足、无权访问合集或卡片、请求在“View as”模式下执行,或组织已被暂停或删除(`detail` 为对象,包含 `code: org_suspended | org_deleted`)。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
application/json
404对象不存在或您无权访问。对于访问受限的对象,API 不会确认其是否存在。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
application/json
409对象状态不允许执行该操作,例如存在重复、正在索引,或作业已处理过。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
application/json
410对象曾经存在,但已不可用:链接已被使用或已过期,或文件已在保留期限结束时删除。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
application/json
422校验错误:请求体或参数不符合定义的结构(`detail` 为校验错误列表),或参数值超出范围(`detail` 为消息)。
响应头
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
application/json
429请求过多(`api.rate_limited`)、组织每分钟、每天或每月的配额已用完(`api.quota_exceeded`;`error.details` 中包含 `quota`、`limit` 和 `reset_at`)、已达到组织的限额,或回答服务繁忙(`answers.engine_busy`)。请等待 `Retry-After` 头中给出的时间。
响应头
Retry-After重试请求前需要等待的秒数。
RateLimit-Policy当前生效的限制,格式遵循 IETF 草案
draft-ietf-httpapi-ratelimit-headers:以逗号分隔的项"<name>";q=<quota>;w=<window in seconds>。key是 API 密钥的请求速率(配额即突发量,时间窗口是配额完全恢复所需的时间;会话为user,无凭据时为ip);minute、day和month是组织按 UTC 计算的自然分钟、自然日和自然月的配额。RateLimitRateLimit-Policy中每项限制的剩余量:"<name>";r=<remaining>;t=<seconds until reset>。X-RateLimit-LimitRateLimit-Policy中最严格一项(剩余请求数最少的一项)的限额。X-RateLimit-Remaining最严格限制下的剩余请求数。
X-RateLimit-Reset距最严格限制重置的秒数。
application/json
错误码
除所有请求通用的错误码外,此接口还可能在 error.code 中返回以下错误码。
安全重试
每个 POST 和 PATCH 请求都传入 Idempotency-Key 头(例如一个 UUID)。24 小时内用同一个键重试时,返回已保存的响应,不会再次执行请求。
速率限制
响应带有 RateLimit 和 RateLimit-Policy 头,以及旧版的 X-RateLimit-Limit、X-RateLimit-Remaining 和 X-RateLimit-Reset 头。429 响应带有以秒为单位的 Retry-After:等待后重试。