Skip to content

Uploads

Last updated 9 Nov 2026

Browsers and apps upload straight to your upload hostname with a URL your server signs. The URL fixes where the file goes, the largest size allowed, the accepted types and the expiry time.

Parameter Meaning
exp Expiry as a Unix time in seconds (UTC)
max_bytes Largest size allowed, in bytes
types Accepted Content-Type values, lower case, separated by ,, such as image/png,image/jpeg

Send the file with PUT to the signed URL, with Content-Type and Content-Length. Chunked transfer encoding is not accepted. binedge checks, in this order:

  1. The signature, the key prefix and the expiry time.
  2. Content-Type, without parameters after ;, is one of types.
  3. Content-Length is no more than max_bytes.
  4. The first bytes of the file match the declared type. A file that says image/png but is not a PNG is rejected. Types that cannot be recognised from the content, such as text/plain or application/octet-stream, are not checked this way.

A 200 with an empty body means the file is stored. Nothing is stored when a check fails or the connection drops before the whole body arrives. Uploading to the same key again replaces the file. A single request can carry up to 300 MB; use resumable uploads for larger files.

binedge implements tus 1.0 with the creation and expiration extensions, so tus clients such as tus-js-client, TUSKit and tus-android-client work unchanged. Use the signed upload URL as the creation endpoint.

Request Behaviour
POST to the signed URL Creates the upload. Send Tus-Resumable: 1.0.0, Upload-Length (1 to max_bytes) and filetype in Upload-Metadata, which must be one of types. Returns 201 and a Location
HEAD to Location Returns Upload-Offset, Upload-Length and Upload-Expires
PATCH to Location Sends the next part with Content-Type: application/offset+octet-stream and the current Upload-Offset. Returns 204 and the new offset
  • Choose a chunk size that is a multiple of 8 MiB. We recommend 64 MiB.
  • Only whole 8 MiB parts are kept. If a PATCH ends in the middle of a part, the returned Upload-Offset is the end of the last whole part, and the client sends again from there.
  • An upload can be resumed for 24 hours after it was created. Unfinished uploads are removed after that.
  • If a PATCH returns 409, send HEAD to read the current offset, then continue from it.
HTTP Meaning
404 The upload has expired or no longer exists
409 Upload-Offset does not match what has been stored
412 Tus-Resumable is missing or is not 1.0.0
413 Upload-Length is larger than max_bytes, or the body is longer than Upload-Length
423 Another PATCH is writing to the same upload

Every response from the upload hostname allows any origin, and the tus headers (Location, Upload-Offset, Upload-Length, Upload-Expires, Tus-Resumable, Tus-Version, Tus-Extension) are exposed to scripts. The signature in the URL is the only credential, so uploads do not use cookies.

binedge does not call your server. When the upload succeeds, your app tells your server, as it would after any other upload, and your server stores the key.