Confirmed upload

Send sequential chunks with Fetch. This same-site example uses the default envelope and a generated 1 MiB Blob, not a personal file.

import { Http, ContentType, uploadConfirmed, type HttpUploadChunkReceipt } from "fetchzen";
const api = Http.create(`${location.origin}/api/examples/`, {
cache: false, secure: false,
});
const body = new Blob([new Uint8Array(1024 * 1024)]);
const result = await uploadConfirmed(body, {
sendChunk: async (chunk, { signal }) =>
(await api.post<Blob, HttpUploadChunkReceipt>("upload-chunk/", chunk, {
type: ContentType.APPLICATION_OCTET_STREAM, signal, retry: 0,
})).payload,
onUploadProgress: (progress) => console.log(progress),
});
console.log(result);
Try this requestServer-confirmed upload
Request parameters

Only Run sends a request to this site's demo API. Use synthetic data only; do not send secrets or personal files. Uploads are counted, not stored.

Ready. No request sent.

Result

Choose Run to see the response.
Event log
No events yet.

Each POST /api/examples/upload-chunk/ reads at most 256 KiB of actual raw body before returning { data: { receivedBytes, stored: false } }. The demo counts and discards bytes; it does not assemble or store files. Progress starts at 0% and advances only on exact receipts, not when bytes are handed to Fetch. done: true means byte receipts, not storage or processing.

The demo limits generated files to 1 MiB. It has no persistence or resume. Use synthetic data: requests pass through Cloudflare. Smaller chunks mean more HTTP round trips. An ordinary whole-file endpoint cannot use this convention without server changes.

Next: production requirements and cancellation or ordinary file upload.