POST/v1/uploads/{upload_id}/complete
Complete an upload
complete_upload
When all parts are received, Sursa assembles the file, compares the SHA-256 of the whole file with sha256 in the body and runs the same checks as for a single-request upload: the format by content signature and antivirus scanning. The result is ready, or rejected with reject_reason (checksum_mismatch, type_mismatch, unsupported_format, infected, scan_unavailable, unsafe_content). Each rejection by the format or antivirus check is written to the audit log as file.rejected.
A 200 response means the result is ready; 202 means the file is still being checked (processing), and the result comes from GET /v1/uploads/{upload_id}. If the status returns to pending (a restart of an API instance interrupted the check), send complete again. Repeating complete after the result returns the same result. Missing parts return 409 uploads.incomplete (details.missing). A sha256 that differs from the one declared at creation, or a parts[].etag that differs from a received part, returns 422 uploads.checksum_mismatch. A ready upload that is not used lives for 24 hours. Added in 1.62.0.
Authentication
Send an API key in the Authorization header: Authorization: Bearer <key>.
Path parameters
upload_idstringrequiredThe upload ID (
upl_followed by 32 hex characters).length ≤ 64
Header parameters
Idempotency-KeystringKey for a safe retry of a write: 1 to 255 printable ASCII characters; a UUID v4 per logical operation is recommended. A retry with the same key within 24 hours does not run the operation again: it returns the saved response (status, headers and body) with the
Idempotency-Replayed: trueheader. The same key with a different method, path,Content-Typeor body returns409 api.idempotency_mismatch; while the first request is still running,409 api.idempotency_in_progresswithRetry-After: 1. After a 5xx or 429 response the key is released, and a retry runs the operation again. The key is scoped to the organization and the caller (API key, user, or custom source key).length ≥ 1, length ≤ 255
Request body
application/json
sha256stringrequiredThe SHA-256 of the whole file.
partsarray of UploadPartRefOptional part check: the ETag of each part as returned by
PUT …/parts/{n}.items ≤ 1000
Responses
200The result is ready: `ready` or `rejected`.
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
Idempotency-Replayedtruemeans the response was replayed from the saved one for thisIdempotency-Key: the operation did not run again.
application/json
idstringrequiredThe upload ID (
upl_followed by 32 hex characters).filenamestringrequiredThe file name (without folders).
content_typestringrequiredThe declared content type; empty if not declared.
sizeinteger (int64)requiredThe file size in bytes.
sha256string | nullrequiredThe SHA-256 of the file, declared at creation or at
complete;nullif not known yet.part_sizeinteger (int64)requiredThe size of each part except the last (from 5 to 100 MiB).
part_countintegerrequiredThe number of parts.
≥ 1, ≤ 1000
parts_receivedintegerrequiredThe number of received parts.
≥ 0
The received parts by number (empty in the
POST /v1/uploadsresponse).reject_reasonstring | nullrequiredThe rejection reason (
rejected):checksum_mismatch,type_mismatch,unsupported_format,infected,scan_unavailable,unsafe_content. The enumeration may grow;nullif not rejected.reject_detailsobject | nullrequiredDetails of the rejection (the extension, the declared and detected format, checksums);
nullif not rejected.created_atstring (date-time)requiredWhen the upload was created.
expires_atstring (date-time)requiredThe deadline to complete the upload and, once it is ready, to use it.
completed_atstring (date-time) | nullrequiredWhen the check finished (
readyorrejected).consumed_atstring (date-time) | nullrequiredWhen the upload was used (by a card, an archive or an import).
202The file is still being checked (`processing`).
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
Idempotency-Replayedtruemeans the response was replayed from the saved one for thisIdempotency-Key: the operation did not run again.
application/json
idstringrequiredThe upload ID (
upl_followed by 32 hex characters).filenamestringrequiredThe file name (without folders).
content_typestringrequiredThe declared content type; empty if not declared.
sizeinteger (int64)requiredThe file size in bytes.
sha256string | nullrequiredThe SHA-256 of the file, declared at creation or at
complete;nullif not known yet.part_sizeinteger (int64)requiredThe size of each part except the last (from 5 to 100 MiB).
part_countintegerrequiredThe number of parts.
≥ 1, ≤ 1000
parts_receivedintegerrequiredThe number of received parts.
≥ 0
The received parts by number (empty in the
POST /v1/uploadsresponse).reject_reasonstring | nullrequiredThe rejection reason (
rejected):checksum_mismatch,type_mismatch,unsupported_format,infected,scan_unavailable,unsafe_content. The enumeration may grow;nullif not rejected.reject_detailsobject | nullrequiredDetails of the rejection (the extension, the declared and detected format, checksums);
nullif not rejected.created_atstring (date-time)requiredWhen the upload was created.
expires_atstring (date-time)requiredThe deadline to complete the upload and, once it is ready, to use it.
completed_atstring (date-time) | nullrequiredWhen the check finished (
readyorrejected).consumed_atstring (date-time) | nullrequiredWhen the upload was used (by a card, an archive or an import).
401No credentials were sent (neither a session cookie nor an API key), or the key was not found.
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
403The action is not allowed: the role is insufficient, there is no access to the collection or card, the request runs in “View as” mode, or the organization is suspended or deleted (`detail` is an object with `code: org_suspended | org_deleted`).
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
404The object does not exist or is not available to you. The API does not confirm that a restricted object exists.
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
409The state of the object does not allow the action, for example a duplicate, indexing in progress, or a job that is already processed.
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
410The object existed but is no longer available: the link was used or has expired, or the file was deleted at the end of its retention period.
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
422Validation error: the body or parameters do not match the schema (`detail` is a list of validation errors), or a parameter value is out of range (`detail` is a message).
Response headers
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
429Too many requests (`api.rate_limited`), the organization's quota for the minute, day or month is used up (`api.quota_exceeded`; `error.details` holds `quota`, `limit` and `reset_at`), the organization's limit is reached, or the answer service is busy (`answers.engine_busy`). Wait for the time in the `Retry-After` header.
Response headers
Retry-AfterNumber of seconds to wait before you retry the request.
RateLimit-PolicyLimits in effect, in the format of the IETF draft
draft-ietf-httpapi-ratelimit-headers: comma-separated items"<name>";q=<quota>;w=<window in seconds>.keyis the request rate of the API key (the quota is the burst, the window is the time to refill it fully; for a session it isuser, without credentialsip);minute,dayandmonthare the organization's quotas for the calendar minute, day and month in UTC.RateLimitWhat is left of each limit in
RateLimit-Policy:"<name>";r=<remaining>;t=<seconds until reset>.X-RateLimit-LimitLimit of the strictest entry in
RateLimit-Policy(the one with the fewest requests left).X-RateLimit-RemainingRequests left under the strictest limit.
X-RateLimit-ResetSeconds until the strictest limit resets.
application/json
Error codes
Codes this endpoint can return in error.code, besides the general codes of every request.
Safe retries
Send an Idempotency-Key header (for example a UUID) with each POST and PATCH. A retry with the same key within 24 hours returns the saved response instead of running the request again.
Rate limits
Responses carry the RateLimit and RateLimit-Policy headers and the earlier X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 response has Retry-After in seconds: wait and retry.