← All posts

Zip Files in S3 with Python and the S3zipper API

Updated 2026-10-21

If you write Python, the S3zipper API gives you a zipped archive of any S3 prefix in a handful of requests — no boto3 multipart plumbing, no temporary files. This is the complete flow.

1. Get a token

import requests

BASE = "https://api.s3zipper.com"

token = requests.post(
    BASE + "/gentoken",
    data={"userKey": "YOUR_USERKEY", "userSecret": "YOUR_USERSECRET"},
).json()["token"]

headers = {"Authorization": f"Bearer {token}"}

Store the key and secret as environment variables; the token expires after a day, so request a fresh one per run.

2. Start the zip job

start = requests.post(
    BASE + "/v1/zipstart",
    headers=headers,
    json={
        "awsKey": "AKIA...",
        "awsSecret": "...",
        "awsBucket": "my-bucket",
        "awsRegion": "us-east-1",
        "filePaths": ["my-bucket/reports/2026"],
        "zipFileName": "reports-2026.zip",
    },
).json()
print(start["size"])  # e.g. "181 MB"

filePaths are full S3 keys: a prefix means "everything under this folder". The response also contains a taskUUID that identifies the job.

3. Poll until it finishes

import time

while True:
    state = requests.post(BASE + "/v1/zipstate", headers=headers, json=start).json()
    if state["State"] in ("SUCCESS", "FAILURE"):
        break
    time.sleep(2)

if state["State"] == "FAILURE":
    raise RuntimeError(state.get("Error"))

4. Get the download URL

result = requests.post(BASE + "/v1/zipresult", headers=headers, json=start).json()
url = result["results"][0]
print(url)

# download it
with requests.get(url, stream=True) as r:
    r.raise_for_status()
    with open("reports-2026.zip", "wb") as f:
        for chunk in r.iter_content(1 << 20):
            f.write(chunk)

The URL is a presigned S3 link, valid for seven days by default. Requesting the result again returns the same link, so it is safe to share until it expires.

Notes for production use

  • Reuse one token for many jobs in the same process; it is valid for 24 hours.
  • Poll with a small back-off on large archives rather than a tight loop.
  • Handle FAILURE explicitly — a bad key, unreadable path or plan limit all come back there with a reason.
  • Add resultsEmail if you would rather receive the link than poll.

Try it on your own bucket

Create a free account and zip S3 files on the fly — no downloads, no local disk.

Create free account API docs

← All posts