Resumable uploads

Upload large files in chunks over the TUS 1.0.0 protocol. If a connection drops, the client asks the server how many bytes it has and continues from there instead of starting over. Available wherever Storage is — no setup.

Endpoint

POST   /storage/v1/upload/resumable
HEAD   /storage/v1/upload/resumable/{id}
PATCH  /storage/v1/upload/resumable/{id}
DELETE /storage/v1/upload/resumable/{id}

The server implements TUS 1.0.0 with the creation and termination extensions. Every request carries Authorization: Bearer <key-or-token>; authorization to write the target object is checked up front against your Row-Level Security on storage.objects. Send an OPTIONS to any resumable path to read the server's capabilities (Tus-Version, Tus-Extension, and Tus-Max-Size).

The flow

1 · Create the upload

POST with the total size in Upload-Length and the target in Upload-Metadata (comma-separated key base64(value) pairs). The recognised metadata keys are bucketName, objectName, and optional contentType. The response is 201 with a Location you use for the rest of the upload:

POST /storage/v1/upload/resumable
Authorization: Bearer <key>
Tus-Resumable: 1.0.0
Upload-Length: 10485760
Upload-Metadata: bucketName YXZhdGFycw==,objectName dXNlcnMvYWxpY2UucG5n,contentType aW1hZ2UvcG5n

→ 201 Created
  Tus-Resumable: 1.0.0
  Location: /storage/v1/upload/resumable/<id>
  Upload-Offset: 0

2 · Send chunks

PATCH each chunk with Content-Type: application/offset+octet-stream and the current Upload-Offset. The offset you send must equal the server's offset, or you get 409 telling you the expected value. Each PATCH returns the new offset:

PATCH /storage/v1/upload/resumable/<id>
Authorization: Bearer <key>
Tus-Resumable: 1.0.0
Content-Type: application/offset+octet-stream
Upload-Offset: 0

<chunk bytes>

→ 204 No Content
  Upload-Offset: 5242880

When the offset reaches Upload-Length the object is finalized and appears in the bucket.

3 · Resume or cancel

After an interruption, HEAD the upload URL to learn the current Upload-Offset, then continue PATCHing from there. DELETE the upload URL to abort and discard staged bytes.

HEAD /storage/v1/upload/resumable/<id>    → 200, Upload-Offset: 5242880
DELETE /storage/v1/upload/resumable/<id>  → 204 (abort)

Clients

Any standard TUS 1.0.0 client works against this endpoint — for the browser, tus-js-client pointed at the resumable URL with your bearer token and the metadata keys above. Resumable upload uses the creation and termination extensions.

Limits and notes