Sending large files to CalmLens one part at a time
Multipart uploads send a large file to CalmLens in ordered parts: how an upload opens, continues and ends, which limits apply and when moderation starts.
·5 min read
Uploads
API
SDK
A single upload request works well for most images and documents. It works less well for a long video or a large PDF, where one interrupted request means sending the whole file again and the full payload has to sit in memory on your side. Multipart uploads let you send that file as a series of parts instead, each in its own request.
Three steps, two methods
A multipart upload has no separate "start" or "complete" call. The first part opens the upload, every later part continues it, and the part you mark as final closes it.
Create the asset with the first part. This uses the same asset creation request as a normal upload, with a part object in place of content. The part carries partNumber: 1 and type, the MIME type of the whole file.
Send each later part to the asset's part endpoint with the next partNumber.
Set isFinal: true on the last part. CalmLens assembles the file and processes it.
In the SDKs, those steps map to creating the asset with its first part and then uploading the rest:
The first response is an asset with status: "uploading". Keep its id, because every later part refers to it. If a file fits in one part, you can send partNumber: 1 with isFinal: true in the first request and the upload opens and closes in one call.
Parts can be passed as base64 strings or byte arrays. If you use base64, split the original bytes first and encode each part separately. Cutting one long base64 string into pieces breaks the encoding at the boundaries, and CalmLens rejects a part that does not decode cleanly.
Parts arrive in order
Parts must be sent one at a time, in order, starting at 1. CalmLens keeps a count of the parts it has received on the asset itself, in uploadPartsReceived, and the next part must be exactly one higher.
Because parts are sequential, that count is all the progress state you need. There are no gaps to track and nothing to reorder when the upload closes. If your process stops halfway through, retrieve the asset, read uploadPartsReceived, and carry on from the following part.
Out-of-order requests fail with a 409 and a specific error code:
Error code
When it happens
upload/invalid-part-number
A part number is skipped or repeated. The error details include expectedPartNumber and receivedPartNumber.
upload/use-upload-part
The creation request carries a part number other than 1. Later parts belong on the part endpoint.
upload/not-open
The asset is no longer accepting parts, for example because the final part has already been received.
Limits
Every part except the last must be at least 5MiB. The final part can be any size. While an upload is open, its parts are held in object storage as a multipart object, and that storage only joins non-final parts of at least this size.
Non-image files can total up to 5GB. If you already know the final size, pass sizeInBytes with the first request. CalmLens checks it against the limit before any data is stored, so an oversized file fails on the first part rather than the last.
The type on the first part has to be a concrete file type such as video/mp4 or application/pdf. Container types like application/octet-stream and multipart/form-data are rejected with upload/invalid-mime-type, because CalmLens can't tell how to process or store the content.
Images can be sent in parts too. When an image upload is finalised, CalmLens may re-encode it to a more efficient format so the stored image stays within the image size limits.
When moderation starts
Nothing is classified while parts are arriving. The intermediate responses only update the asset's size and part count. Once the final part arrives, CalmLens assembles the parts into a single file, finalises the asset's format and checksums, and then hands it to classification in the same way as a single-request upload.
The part endpoint takes the same queue flag as asset creation, so you decide how the final request behaves:
With queue=true, the asset is queued for classification and the final request returns straight away. Use asset events or webhooks to learn when the report is ready.
With queue=false, which is the part endpoint's default, classification runs before the response returns, and the final response carries the classified asset.
Retention follows your processing options. If you haven't asked CalmLens to keep content after processing and you classify in the request, the assembled file can be removed from storage immediately, with classification running on the bytes already in memory. The asset record and its moderation results remain.
SDK support
The JavaScript SDK covers both halves of the flow: assets.create accepts a part in place of content, and assets.uploadPart sends each following part to the asset you created. Both validate a part before sending it, including the 5MiB minimum for non-final parts and the base64 boundary check, so a malformed part fails locally instead of after a network round trip.
To upload a file from disk, read it in chunks of at least 5MiB, send each chunk with the next part number, and set isFinal on the last one.
We use essential cookies to keep you signed in and the site secure. With your permission, we'll also use functional cookies to remember preferences such as your layout and documentation language, and to offer Google One Tap sign-in. We don't use analytics or advertising cookies. Manage cookies