WebSocket upload
Upload a known-size file or an unknown-length media stream to an existing project. Interrupted uploads can be resumed while their server-side upload state remains active.
Connection
wss://{server}/ws/v2/Upload?id={projectId}[&transcodingProfile={name}][&completeOnTimeout={bool}]
Query parameter |
Required |
Default |
Description |
|---|---|---|---|
|
Yes |
N/A |
Target project ID. The authenticated user must have access to it. |
|
No |
|
Transcoding profile selected when a new upload is initialized. A value sent when resuming an existing upload has no effect. |
|
No |
|
When |
Protocol sequence
Connect and authenticate.
Receive the server’s
FileStateInfoJSON text message.Send the client’s
FileStateInfoJSON text message.Send binary data messages while concurrently receiving text progress messages.
Complete the upload according to its known-size or unknown-length completion procedure.
Server handshake
The first server message is JSON text. Property names use PascalCase.
Example for a new upload:
{
"IsInitialized": false,
"FileName": null,
"BufferSize": 32768,
"TotalFileSize": 0,
"CurrentFileOffset": 0,
"Tag": null
}
Property |
Type |
Client handling |
|---|---|---|
|
Boolean |
|
|
Integer |
Use as the maximum size of one complete binary WebSocket message, including its 10-byte header. |
|
Integer |
Use as the number of bytes already stored. It is |
|
String or |
Ignore. |
|
Integer or |
Ignore. |
|
String or |
Ignore. |
Client handshake
Reply with one JSON text message. Property names are case-sensitive and use PascalCase.
Known-size file:
{
"FileName": "recording.mp4",
"TotalFileSize": 5242880,
"CurrentFileOffset": 0
}
Unknown-length stream:
{
"FileName": "stream.ts",
"TotalFileSize": null,
"CurrentFileOffset": 0
}
Property |
Type |
Requirement |
|---|---|---|
|
String |
Name of the uploaded media. |
|
Integer or |
Exact positive byte count for a known-size file. Use |
|
Integer |
Use |
The server initializes a new upload after accepting this message.
Binary data messages
Each binary WebSocket message has the following layout:
offset | count | data
Field |
Size |
Encoding |
Requirement |
|---|---|---|---|
|
8 bytes |
Little-endian IEEE-754 |
Non-negative integer byte position of this chunk in the complete upload. Must equal the number of bytes already stored by the server. Maximum exact value is |
|
2 bytes |
Little-endian signed |
Number of bytes in |
|
|
Raw bytes |
Media bytes beginning at |
Message-size limits
Value |
Calculation |
Default |
|---|---|---|
Header size |
|
10 bytes |
Maximum message size |
|
32,768 bytes |
Maximum data size |
|
32,758 bytes |
BufferSize applies to the complete logical WebSocket message. A message may use multiple WebSocket frames, but their combined content must not exceed this limit.
Offset sequence
Chunk |
Offset |
Count |
Next offset |
|---|---|---|---|
First |
|
|
|
Second |
|
|
|
Third |
|
|
|
Skipped, overlapping, and retransmitted byte ranges are rejected.
JavaScript encoding example
function createUploadMessage(offset, data) {
const headerSize = 10;
const message = new ArrayBuffer(headerSize + data.byteLength);
const view = new DataView(message);
view.setFloat64(0, offset, true);
view.setInt16(8, data.byteLength, true);
new Uint8Array(message, headerSize).set(data);
return message;
}
Progress messages
The server periodically sends text progress messages containing the number of uploaded bytes.
Completing an upload
Upload type |
Client action |
Server action |
|---|---|---|
Known-size file |
Send exactly |
Completes the upload and closes with |
Unknown-length stream |
Send a normal WebSocket close ( |
Treats the normal close as the end of the stream and completes the upload. |
Timeout completion |
Connect with |
Completes the upload when the WebSocket receive timeout expires. |
Completion rules:
Do not send more bytes than the declared
TotalFileSize.A normal client close before a known-size upload reaches
TotalFileSizecancels that upload.A dropped connection or non-normal close leaves the upload resumable until the upload timeout expires.
completeOnTimeout=truecan complete a known-size upload before it reachesTotalFileSize; use it only when inactivity intentionally marks completion.
Resuming an interrupted upload
Reconnect with the same project ID before the upload timeout expires.
When the server handshake contains IsInitialized: true:
Read
CurrentFileOffsetfrom the server handshake.Seek the media source to that absolute byte position.
Send the same value as
CurrentFileOffsetin the client handshake.Set the first binary message’s
offsetto that same value.Increase subsequent offsets by each preceding message’s
count.
Resume rule |
Requirement |
|---|---|
Offset basis |
Binary offsets are positions in the complete upload, not byte counts relative to the new connection. |
Source access |
The client must be able to reproduce data beginning at |
Restart |
An initialized upload cannot be restarted from offset |
Connection replacement |
A new connection for the upload replaces its previous WebSocket. |
Deadline |
Resume before the server-side upload timeout expires. |
Timeouts
Timeout values are server-configured. Typical values are:
Timeout |
Typical value |
Starts or resets |
Expiry behavior |
|---|---|---|---|
WebSocket receive timeout |
60 seconds |
After the client handshake and after each received data message |
With |
Upload timeout |
120 seconds |
When the upload is initialized and whenever data is written |
Stops the upload and removes the opportunity to resume. |
Server-to-client progress messages do not reset either timeout.
Errors
Close-reason text can vary between server versions. Use the close code and current protocol state for error handling.
Situation |
Close code |
|---|---|
Authentication failed or required claim is missing |
|
Project ID is missing |
|
Project does not exist or is inaccessible |
|
An incompatible operation is already running on the project |
|
Upload is already completed |
|
|
|
Resume handshake contains an incorrect offset |
|
Binary message contains a non-contiguous offset |
|
WebSocket receive timeout with |
|
Message exceeds |
|
Declared |
|
Unexpected server error |
|