Node.js is a natural fit for a zip workflow: you trigger it from a web request and want the work to happen elsewhere. The S3zipper API lets you do exactly that — start a background job, poll it, and hand the signed download URL back to the browser.
1. Exchange your key for a token
const BASE = "https://api.s3zipper.com";
const tokRes = await fetch(`${BASE}/gentoken`, {
method: "POST",
body: new URLSearchParams({ userKey: process.env.S3Z_KEY, userSecret: process.env.S3Z_SECRET }),
});
const { token } = await tokRes.json();
const headers = { Authorization: `Bearer ${token}`, "Content-Type": "application/json" };
2. Start the zip
const start = await fetch(`${BASE}/v1/zipstart`, {
method: "POST",
headers,
body: JSON.stringify({
awsKey: process.env.AWS_ACCESS_KEY_ID,
awsSecret: process.env.AWS_SECRET_ACCESS_KEY,
awsBucket: "my-bucket",
awsRegion: "us-east-1",
filePaths: ["my-bucket/exports/2026-10"],
zipFileName: "exports-2026-10.zip",
}),
}).then((r) => r.json());
filePaths are full S3 keys — a folder prefix zips everything below it. The response contains a taskUUID and reports the total size.
3. Poll for completion
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
let state;
for (let i = 0; i < 120; i++) {
state = await fetch(`${BASE}/v1/zipstate`, {
method: "POST",
headers,
body: JSON.stringify(start),
}).then((r) => r.json());
if (state.State === "SUCCESS" || state.State === "FAILURE") break;
await sleep(2000);
}
if (state.State !== "SUCCESS") throw new Error(state.Error || "zip failed");
4. Return the download URL
const result = await fetch(`${BASE}/v1/zipresult`, {
method: "POST",
headers,
body: JSON.stringify(start),
}).then((r) => r.json());
const url = result.results[0]; // presigned S3 URL
res.redirect(url); // or return it as JSON
The URL is signed and expires (seven days by default). It is safe to hand to the user and safe to request again.
Tips
- Keep the token for the process lifetime — it lasts 24 hours.
- Do not run the loop on the request path for huge archives; return the task id to the client and poll from there, or use
resultsEmail. - Store credentials in environment variables, never in code.