New500 GB of stream delivery, free every month

“Download all as ZIP,”
as a service.

Send a list of file URLs. Your users get one download link — and Eazip handles everything that happens after the click.

Plan it with your coding agent

Summer shoot

100 photos · 277 MB

Your app, your button. Eazip does everything after the click.

await fetch('https://api.eazip.io/jobs', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.EAZIP_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    zip_filename: 'summer-shoot.zip',
    files: [
      { url: 'https://cdn.yourapp.com/summer/DSC_0001.jpg' },
      { url: 'https://cdn.yourapp.com/summer/DSC_0002.jpg' },
    ],
  }),
});

// You get one download link for your user.

The button is easy.
The next four days aren’t.

Follow one “Download all” click from request to cleanup. Every step below is handled by Eazip, on every plan.

  1. +00:00:00

    A client clicks “Download all.”

    Your server sends Eazip one request with the 800 file URLs of their 40 GB wedding gallery. Presigned S3, R2, and Supabase links work as they are.

    POST/jobs
    {
      "files": [ …800 file URLs… ],
      "mode": "stored",
      "expires_in": 345600,
      "max_zip_size_bytes": 10000000000
    }
  2. +00:00:01

    Eazip starts fetching.

    Files are pulled server-to-server and written into the ZIP as they arrive. Nothing passes through your servers, and there is no bucket CORS to configure.

    • S3presigned URLEazip
    • R2presigned URLEazip
    • Supabase Storagepresigned URLEazip
  3. +00:00:48

    One source times out.

    Eazip retries it. If it still fails, you decide what happens: fail the job, or finish without that file and report it.

    photos/0312.jpgtimed outretried ✓

    "fail_on_url_error": trueThe job fails. Nothing half-finished reaches the client.

    "fail_on_url_error": falseThe ZIP completes without it; the URL is listed in the job’s errors.

  4. +00:03:10

    The archive passes 4 GB.

    ZIP64 is always on, so big archives stay valid. With a split size set, the 40 GB gallery arrives as 10 GB parts.

    1. shoot_01.zip10.0 GB
    2. shoot_02.zip10.0 GB
    3. shoot_03.zip10.0 GB
    4. shoot_04.zip9.6 GB
  5. +00:06:02

    Ready.

    A webhook tells your app, and the client gets signed download links that expire when you say.

    POSTyour-app.com/webhooks/eazip
    {
      "event": "job.completed",
      "job_id": "9c4d2f8e-1234-5678-90ab-cdef01234567",
      "zip_count": 4,
      "zips": [ { "filename": "shoot_01.zip",
                  "download_url": "https://api.eazip.io/download/eyJ…" },
                … ]
    }
  6. +00:08:05

    The hotel wifi drops at 61%.

    The download picks up where it stopped. Nobody starts a 10 GB file over.

    connection lost at 6.1 GBresumed · 10.0 GB ✓
  7. +1d 09:12

    They need it again tomorrow.

    The stored ZIP is still there, so nothing is rebuilt. It is served from Eazip’s storage — your bucket isn’t touched again, and there is no egress fee.

    1. Download 1day 0 · hotel
    2. Download 2day 1 · studio
    3. Download 3day 2 · the couple’s parents
  8. +4d 00:00

    Retention ends.

    The archive is deleted on schedule. There is no temp storage or cleanup cron for you to run. Keep ZIPs up to 4 days on Free, or up to 90 on Scale.

    1. shoot_01.zipdeleted
    2. shoot_02.zipdeleted
    3. shoot_03.zipdeleted
    4. shoot_04.zipdeleted

An illustrative stored job for a 40 GB gallery. Real timings depend on your sources.

  • Public keysCall Eazip from a browser without exposing a secret.
  • AllowlistsRestrict which origins and source hosts a key can use.
  • Hard capsFree stops at the quota. Paid overage is optional.
  • Job historyEvery job and per-file error, in the dashboard.

Made for exports
that get heavy.

800 files · 40 GB

Photo delivery and client galleries

A shoot is 800 files and 40 GB. The client clicks once, gets one link, and can pick it up again tomorrow on hotel wifi — no “your download is being prepared” email.

Attachments · invoices · audits

Client portals and document collection

Attachment bundles, invoice exports, audit archives. The request every B2B customer eventually files, without a queue and a cleanup cron in your app.

400 RAW files

DAM and brand asset libraries

The team selects 400 RAW files across folders and gets one archive. Zero egress on delivery is what makes the math work at that size.

Carrying our own traffic
since before this page.

Eazip started as the export layer of our own file-sharing product and still carries that traffic every day.

jobs run
9,000+
archives built
14,000+
files zipped
7.6M+
archived volume
100 TB+

As of Aug 2, 2026

Free to launch.
Affordable to grow.

Every feature is on every plan, Free included. Start with 500 GB of stream delivery a month, and add capacity and longer retention from $9/month as usage grows.

Free

$0/month

Stream delivery
500 GB / month
Stored
100 GB-days / month
Keep ZIPs
up to 4 days
Card
Not required · hard-capped
Start free

StarterPopular

Your first production export.

$9/mo

Stream
4 TB
Stored
3,000 GB-days
Keep
14 days
Start Starter

Pro

Export is a core workflow.

$29/mo

Stream
10 TB
Stored
20,000 GB-days
Keep
60 days
Start Pro

Scale

High volume, large archives.

$99/mo

Stream
40 TB
Stored
75,000 GB-days
Keep
90 days
Start Scale

Optional extra usage on paid plans: stream $4/TB, stored $2/TB-day. Switch it off and jobs stop at the quota.

Stream builds the ZIP during each download and is billed by the amount downloaded.

Stored builds it once and is billed by size × days kept — 100 GB-days is 100 GB for 1 day, or 25 GB for 4 days.

Every plan: no file-count limit, jobs up to 500 GB, split into ZIPs of up to 50 GB each.

Before you sign up.

What’s the difference between stream and stored?

Stream builds the ZIP while your user downloads it and keeps nothing afterwards; it’s billed by the amount downloaded. Stored builds the archive once and keeps it for your retention window; it’s billed by size × days kept. If the same ZIP may be downloaded more than once, use stored.

What does Free include, and what happens at the quota?

Every month, 500 GB of stream delivery and 100 GB-days of stored archives (for example, 25 GB kept for 4 days), with every feature and no card. Free is hard-capped: once you reach the quota, new stored jobs and stream downloads are rejected until it resets. You’re never billed.

Can I use S3 or R2 presigned URLs?

Yes, and it’s the recommended way to share private files. Presign each object (S3, R2, GCS, Supabase Storage and others) and send the URLs; your bucket credentials never leave your server. They need to stay valid until the ZIP is built for stored jobs, and until your users finish downloading for stream jobs.

Do I need an SDK?

No. Eazip is one HTTP API, so any backend can call it with fetch or cURL. For frontends there are optional open-source packages, @eazip/react and @eazip/core (Eazip.js). They add a download tray with progress, cancel, and retry, and can zip smaller sets right in the browser while larger jobs go to Eazip.

Can I call it straight from the browser, without a backend?

Yes. Create a public key in the dashboard. It’s safe to ship in your frontend: it only works from the sites and file hosts you allow, within the delivery modes, file counts, and job sizes you set. Secret API keys stay on your server.

Ship the button.
We’ll take the next four days.

Want to try the open-source library first? npm i @eazip/react · Eazip.js