Skip to content

Transfer and export Files

Stream bytes, build an inventory and export retained work.

Stream bytes through the SDK

For a seekable source, prepareFileUploadFromSource computes the immutable request with bounded reads. Persist that request, then call uploadFileFromSource with the same bytes. Every reread part is checked before dispatch. Reopening a source does not allow changing the saved operation, content or deadline. The caller closes its source on success, failure or cancellation. CLI files put uses bounded reads too.

Before uploading parts, the SDK now inspects the existing operation and sends only absent parts. A lost response after an accepted part therefore does not require sending that part again. It still checks the entire local source against the frozen request, and the API verifies the completed object before publication. Use files finalize UPLOAD_ID when all bytes are already uploaded and you no longer have the source. Admission replay preserves the original expiry and returns an expired result once that deadline passes.

For explicit inspection, use agent-workplace files parts UPLOAD_ID --json, SDK getFileUploadedParts(auth, { workplaceId, uploadId }), or authenticated GET /v1/files/uploads/{uploadId}/parts?workplaceId=WORKPLACE_ID. The response contains upload (the current operation status) and presentPartNumbers. For an open upload, this is a complete list of present manifest positions, at most 239; [] means none are present. null means inspection does not apply to the current state, such as creation, completion or a terminal result. Inspect upload to decide whether to wait, finalize, or handle its terminal outcome.

This is presence and size evidence, not checksum verification. Part numbers do not prove content integrity, and the response never includes provider identifiers, ETags or grants. Current authority is checked before and after storage inspection. Incomplete, duplicate, malformed or unavailable listings fail; clients must not interpret an error or null as an empty list and retransmit. Grants and finalization remain separate authorized operations. This observation is not a lock against another process or an already-issued write grant; serialize retries of one operation.

downloadFileTo writes to an asynchronous sink with backpressure and returns file metadata only after full SHA-256 verification. It pins the revision and renews short-lived grants for bounded Range reads, rechecking current access. It never switches to a newer revision when pinned content expires or becomes unavailable.

To retain progress, save the revision reference, byte length and SHA-256 before starting. Supply resume with those values and the durable offset, and give the sink a read(offset, length) function for its existing prefix. The SDK rehashes that prefix; a saved digest or offset alone does not prove integrity. A sink's checkpoint(offset) must flush bytes durably before saving that offset. Keep all partial output untrusted and unpublished until the download succeeds. The sink owner closes resources and handles interrupted writes and local file ownership.

The bounded source/sink methods support decimal 2 GB (2,000,000,000 bytes). uploadFile and downloadFile remain whole-buffer methods capped at 64 MiB. The latter rejects larger declared content before fetching object bytes.

Build an inventory with the SDK

Use walkFilesTree for the active current contents of a folder. Omit parentId for the workplace root. Each file event includes pinned revision metadata:

for await (const item of client.walkFilesTree(auth, {
  workplaceId,
  parentId,
})) {
  if (item.kind === "file") {
    // Select a safe destination yourself; item.path contains untrusted names.
    console.log(item.path, item.file.revisionReference);
  }
}

Use walkRetainedFiles for all retained workplace work, including previous revisions and trash. Entry events preserve folder relationships, names and trash metadata; revision events include expiry and restoration metadata:

for await (const item of client.walkRetainedFiles(auth, { workplaceId })) {
  if (item.kind === "revision") {
    console.log(item.file.revisionReference, item.file.isCurrent);
  }
}

Both methods stream metadata through ordinary authorized API reads. They do not fetch bytes or grant access to content that has expired or been purged. Use downloadFileTo with each pinned revision to copy its bytes. Retention and permissions can still change before that read.

An inventory is not a snapshot. The start event carries a change checkpoint. An issue event reports content that disappeared or a tree entry encountered again during concurrent moves. A file event's changedSinceListing flag reports a version change between listing and metadata resolution. The final complete event means enumeration ended, not that every file was downloaded: inspect its issue count. workplaceChanges reports observed, none_observed, or unknown for the enumeration interval. unknown means change-history coverage is incomplete. Changes may concern other folders. Authorization and transport errors stop iteration and propagate to the caller. If copying bytes afterward, check changes again from the start checkpoint to cover that additional interval.

Names and path segments are untrusted. A filesystem consumer must handle unsafe names, case collisions, symbolic links and existing destinations without silently overwriting local work. These methods do not provide archive restoration or extend any retention period.

The tree walker retains one page per traversal depth and a visited-ID index. By default that index grows with the number of entries. Large consumers can pass { visits } as the third argument, implementing FilesTreeVisitStore.addIfNew(id) with a fresh store for each traversal. Return true exactly once per ID and propagate storage failures. The CLI uses a disk-backed index. Retained inventory uses ordered pages without a global visited-ID index.

Download a folder or export retained work

Use the default saved CLI credential. Create a private directory for the operation records before either command:

mkdir -p private-files
chmod 700 private-files

Download the active current contents beneath a folder, or use root for all active current Files:

agent-workplace files get-folder root \
  --output ./current-files --operation private-files/current-export.json --json

Export all retained workplace Files, including previous revisions and trash:

agent-workplace files export \
  --output ./retained-files --operation private-files/retained-export.json --json

Both commands require a new destination directory whose parent exists and a private operation path outside that destination. Recovery currently requires a POSIX filesystem. Keep the operation file and its adjacent private .awp-export-* directory until you finish recovery. These contain the inventory, directory and per-file receipts; their disk usage grows with the exported metadata and attempts. They contain no saved API keys or temporary grants.

Folder downloads use the observed names and create empty folders. Retained exports store bytes under files/FILE_UUID/REVISION_UUID; manifest.ndjson preserves names, parent relationships, empty-folder metadata, trash, revision expiry and restoration metadata. Folder-download manifests live in the private operation directory to avoid colliding with remote names. The result reports both manifest and inventory paths. This is a Files export, not a Mail export or an archive-import/restore interface.

The CLI finishes and saves its inventory before copying content, then downloads pinned revisions with byte-length and SHA-256 verification. It streams file bytes and inventory records, rather than loading all content or entries into memory. Unsafe names, local collisions, missing content and authorization failures are reported instead of silently overwriting or skipping work. Retention still applies: export does not reserve content or extend its lifetime.

Repeat the exact command to resume its saved inventory and interrupted file checkpoints. Completed files are verified again using current authorization. A frozen inventory is not refreshed on retry: choose a new operation and new destination to discover later changes or resolve inventory omissions. Unknown files, replaced directories and unrecorded ownership after a crash are preserved; when safe recovery cannot be established, the command refuses to overwrite them.

The result is explicitly non_snapshot. workplaceChanges covers inventory and content copying, and can reflect changes outside a selected folder. observed means changes occurred; none_observed is not a snapshot guarantee. An expired change window reports unknown and a partial result. Concurrent changes can leave an export that completed its recorded inventory without representing one instant in time.

With --json, stdout contains the result, including plannedFiles, copied, failed, unattempted, stopped, and manifest paths. failed counts issues, including folder failures, not just failed payloads. A partial result also exits nonzero and emits a safe diagnostic on stderr. On lost authority the CLI stops further downloads and reports unattempted content. Each manifest attempt contains observed inventory records, successful downloads, failures and a final result if that attempt reaches completion; a killed attempt may have no final result. Inspect the latest result and its manifest before treating an export as complete.

On this page