SDK File Uploads

Upload files to a workspace bucket via the Aeontel SDK using the multipart R2 lifecycle.

Files live in workspace-scoped R2 buckets and upload through a three-step lifecycle: create → PUT parts → complete. The SDK ships a runUpload helper that runs the full flow for you.

One-shot upload

TypeScript
import Aeontel, { runUpload } from "@aeontel/sdk";

const client = new Aeontel("sec_...");

const { promise } = runUpload(client, {
  workspaceId: "wsp_...",
  blob: new Blob([bytes], { type: "application/pdf" }),
  filename: "invoice.pdf",
  onProgress: (sent, total) => {
    console.log(`${((sent / total) * 100).toFixed(1)}%`);
  },
});

const file = await promise;
console.log(file.id, file.status); // "fil_...", "ready"

runUpload returns a { promise, abort } handle. Call abort() to cancel cleanly — it stops in-flight part PUTs and marks the upload aborted.

Options

OptionTypeNotes
workspaceIdstringRequired — workspace the file belongs to
blobBlobRequired — file bytes (use File in the browser)
filenamestringFalls back to blob.name if omitted
contentTypestringFalls back to blob.type
directoryIdstringDefaults to the workspace root directory
concurrencynumberParallel part PUTs, default 4
onProgress(sent, total) => voidByte-level progress
onStatus(status) => voidinitiating, uploading, completing, ready, error, aborted

Manual control

Need to stream bytes from somewhere unusual (S3 proxy, Worker origin)? Drive the lifecycle by hand:

TypeScript
// 1. Reserve a file row and get presigned part URLs
const init = await client.files.create({
  workspaceId: "wsp_...",
  name: "big.bin",
  contentType: "application/octet-stream",
  size: blob.size,
});

// 2. PUT every part to init.parts[i].url — R2 returns an ETag per part

// 3. Finalize — passes the ETags back so R2 assembles the object
const file = await client.files.completeUpload({
  id: init.file.id,
  parts: etaggedParts,
});

For big files, call client.files.signUploadParts to mint additional presigned URLs once the initial batch is consumed.