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

id

Yes

N/A

Target project ID. The authenticated user must have access to it.

transcodingProfile

No

default

Transcoding profile selected when a new upload is initialized. A value sent when resuming an existing upload has no effect.

completeOnTimeout

No

false

When true, a WebSocket receive timeout completes the upload. When false, the connection ends without completing the upload.

Authorization

The authenticated user must have the websockets:Upload claim. Use either authentication mechanism:

Mechanism

Request value

Use

Authorization header

Authorization: {authToken}

Clients that can set headers on the WebSocket handshake. Send the Beey token directly, without a Bearer prefix.

WebSocket subprotocol

Sec-WebSocket-Protocol: {authToken}

Browser clients and clients that cannot set the Authorization header. The token must be a valid RFC 7230 token without spaces; the server echoes it as the selected subprotocol.

Browser example:

const socket = new WebSocket(url, authToken);

Protocol sequence

  1. Connect and authenticate.

  2. Receive the server’s FileStateInfo JSON text message.

  3. Send the client’s FileStateInfo JSON text message.

  4. Send binary data messages while concurrently receiving text progress messages.

  5. 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

IsInitialized

Boolean

false identifies a new upload. true identifies an existing resumable upload.

BufferSize

Integer

Use as the maximum size of one complete binary WebSocket message, including its 10-byte header.

CurrentFileOffset

Integer

Use as the number of bytes already stored. It is 0 for a new upload and the resume position for an existing upload.

FileName

String or null

Ignore.

TotalFileSize

Integer or null

Ignore.

Tag

String or null

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

FileName

String

Name of the uploaded media.

TotalFileSize

Integer or null

Exact positive byte count for a known-size file. Use null for an unknown-length stream. Zero and negative values are rejected.

CurrentFileOffset

Integer

Use 0 for a new upload. For an existing upload, copy the exact value from the server handshake.

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

offset

8 bytes

Little-endian IEEE-754 Float64

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^53 - 1.

count

2 bytes

Little-endian signed Int16

Number of bytes in data. Must be positive and must not exceed BufferSize - 10.

data

count bytes

Raw bytes

Media bytes beginning at offset.

Message-size limits

Value

Calculation

Default

Header size

8 + 2

10 bytes

Maximum message size

BufferSize

32,768 bytes

Maximum data size

BufferSize - 10

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

0

32758

32758

Second

32758

32758

65516

Third

65516

1000

66516

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 TotalFileSize bytes and wait for the server close.

Completes the upload and closes with 1000 Upload finished after receiving the declared size.

Unknown-length stream

Send a normal WebSocket close (1000) after the final binary message.

Treats the normal close as the end of the stream and completes the upload.

Timeout completion

Connect with completeOnTimeout=true and stop sending messages.

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 TotalFileSize cancels that upload.

  • A dropped connection or non-normal close leaves the upload resumable until the upload timeout expires.

  • completeOnTimeout=true can complete a known-size upload before it reaches TotalFileSize; 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:

  1. Read CurrentFileOffset from the server handshake.

  2. Seek the media source to that absolute byte position.

  3. Send the same value as CurrentFileOffset in the client handshake.

  4. Set the first binary message’s offset to that same value.

  5. 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 CurrentFileOffset.

Restart

An initialized upload cannot be restarted from offset 0.

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 completeOnTimeout=false, closes the connection without completing the upload. With true, completes the upload.

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

1008

Project ID is missing

1008

Project does not exist or is inaccessible

1001

An incompatible operation is already running on the project

1008

Upload is already completed

1008

TotalFileSize is zero or negative

1008

Resume handshake contains an incorrect offset

1008

Binary message contains a non-contiguous offset

1008

WebSocket receive timeout with completeOnTimeout=false

1008

Message exceeds BufferSize

1009

Declared count exceeds the available message capacity

1007

Unexpected server error

1011