Zum Hauptinhalt springen

Upload

The Streamdiver API works with an S3-compatible object storage hosted on GDPR-compliant infrastructure. For API uploads you can choose between a multipart procedure and a single PUT request. We recommend multipart uploads with presigned URLs — a scalable, performant transfer that needs nothing more than standard HTTPS PUT requests, with no S3 client or credentials to manage. For files larger than 5GB the multipart procedure is required, as a single PUT request is limited to 5GB by the storage backend. For smaller files, such as most audio or image assets, the PUT request upload is a reliable and easy-to-implement approach.

In general the upload is performed in three steps: create, run and complete.

Create & Run Upload

Using the Bearer token from the authentication request as described in Authentication, you have to create an Upload for your Media asset using the fileName of your file as an input. Controlled by the type property, you can select multipart uploads with presigned URLs (s3-multipart-presigned, recommended and the default) or a single HTTP PUT request (put).

Deprecated

The s3-multipart upload method (an S3 client with temporary credentials) is deprecated and is being removed. If your integration uses it, please switch to the presigned multipart method (s3-multipart-presigned), which requires no S3 SDK or stored credentials. The s3-multipart method keeps working until a cut-off date that will be announced with advance notice.

When creating an Upload for a video or audio asset, specify the transcriptLanguageCode to set the language model for automatic transcription. Available language codes are tenant-specific and can be obtained from the transcription languages endpoint.

Continue with your chosen upload procedure!

Simple Upload

The simplest way to upload a file is with a single PUT request. This method is limited to files up to 5GB — for larger files use the multipart upload. To use this upload method, create a new Upload with type set to put:

curl --request POST \
--url https://api.streamdiver.com/v2/uploads \
--header 'Authorization: Bearer {token}' \
--header 'Content-Type: application/json' \
--data '{ "fileName": "myVideo.mp4", "type": "put" }'

Once you got the Upload response, retrieve the already authenticated upload URL from the url property of the input object. This URL can be used immediately to upload the source file like:

curl --request PUT --upload-file myVideo.mp4 "https://storage-example.streamdiver.com/mytenant/videos/2022/12/65e6adcf-175a-400d-8a0c-f20a099157ce.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."

Multipart upload with presigned URLs

For large files we recommend multipart uploads with presigned URLs. The file is split into parts, and each part is signed on demand and uploaded with a standard HTTPS PUT request — no S3 client and no credentials are required.

Create a new Upload with type set to s3-multipart-presigned, optionally providing the total fileSize in bytes:

curl --request POST \
--url https://api.streamdiver.com/v2/uploads \
--header 'Authorization: Bearer {token}' \
--header 'Content-Type: application/json' \
--data '{ "fileName": "myVideo.mp4", "fileSize": "734003200", "type": "s3-multipart-presigned" }'

The id property of the Upload response identifies the upload in all subsequent part operations.

Split the file into parts of a size of your choosing and number them as a continuous sequence starting at 1. The storage backend requires each part except the last to be in range from 5 MB to 5 GB, and an upload can consist of at most 10,000 parts. Within these limits, look for a sweet spot when choosing the part size: too small parts add per-part overhead (every part needs its own sign request and PUT) and can noticeably prolong the upload, while too large parts reduce the benefit of parallel uploading and make retrying a failed part more expensive. For most scenarios a part size in the tens to low hundreds of megabytes (for example 50 MB) is a good starting point.

For each part, request a presigned URL from the sign upload part endpoint:

curl --request GET \
--url https://api.streamdiver.com/v2/uploads/{uploadId}/parts/1/sign \
--header 'Authorization: Bearer {token}'

The response contains the presigned url for the part and its expiry:

{
"data": {
"url": "https://storage-example.streamdiver.com/...&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&...",
"expiresAtUtc": "2024-12-12T23:20:30.50Z"
}
}

Upload the part with an HTTP PUT to that URL and capture the ETag response header — you need it to complete the upload:

curl --request PUT --dump-header - \
--data-binary @part-1.bin \
"https://storage-example.streamdiver.com/...&partNumber=1&X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
# Response headers include: ETag: "d41d8cd98f00b204e9800998ecf8427e"

Presigned URLs are generated on demand and expire after a short period — if a URL expires or a part fails, simply request a fresh URL for that part and retry.

The parts are independent, so they can also be uploaded in parallel — a concurrency of 4–8 PUTs works well for most scenarios. Parallel uploading hides the per-part overhead of signing and issuing the individual requests, which otherwise accumulates when the parts are uploaded one by one. With reasonable concurrency a multipart upload saturates a typical connection just like a single PUT does, and on fast and/or long-distance connections — where a single HTTPS connection cannot fully utilize the available bandwidth — it transfers significantly faster.

To resume an interrupted upload, call list uploaded parts to see which parts (including their etag) are already stored, and upload only the missing ones:

curl --request GET \
--url https://api.streamdiver.com/v2/uploads/{uploadId}/parts \
--header 'Authorization: Bearer {token}'

Because each part is a standard HTTPS PUT, you can use any HTTP client — curl or your language's standard HTTP library. The flow is compatible with the @uppy/aws-s3 plugin, which can serve as a reference client implementation of the sign-per-part procedure.

CORS

The storage is protected by a CORS policy that rejects requests from unknown domains. Uploading directly from a browser therefore only works from domains that are explicitly allowed by Streamdiver.

Once all parts are uploaded, continue with Complete Upload, passing the collected part numbers and ETags.

Complete Upload

After the upload has finished you have to call Complete upload to mark it as completed. This triggers further processing (transcoding and metadata extraction) of the asset. The parameter uploadId can be extracted from the id property of the Upload response provided in the first step.

Pass an optional channelId query parameter to assign the asset to a specific channel. If omitted, the asset is assigned to the default channel.

For presigned multipart uploads, include the uploaded parts (their partNumber and etag) in the request body, so the object can be assembled from its parts:

curl --request PUT \
--url 'https://api.streamdiver.com/v2/uploads/{uploadId}/complete?channelId={channelId}' \
--header 'Authorization: Bearer {token}' \
--header 'Content-Type: application/json' \
--data '{ "parts": [ { "partNumber": 1, "etag": "..." }, { "partNumber": 2, "etag": "..." } ] }'

For the simple PUT upload the body can be omitted:

curl --request PUT \
--url 'https://api.streamdiver.com/v2/uploads/{uploadId}/complete?channelId={channelId}' \
--header 'Authorization: Bearer {token}' \
--header 'Content-Type: application/json'

In the response you get the assetId property (the ID of your Media asset), which can be used for further asset-specific requests against the Streamdiver API. You can retrieve your Media asset with a GET /media/{assetId} request.

Cancel Upload

If you decide not to finish an upload — for example because the user aborted it — call Cancel upload to mark it as cancelled:

curl --request PUT \
--url 'https://api.streamdiver.com/v2/uploads/{uploadId}/cancel' \
--header 'Authorization: Bearer {token}'

Any files already transferred to storage — including parts of a multipart upload — are deleted, and no further processing is scheduled. This is the recommended way to clean up abandoned multipart uploads, as uploaded parts otherwise remain in storage.