← Back to Learn

Engineering Lessons: Code That Worked and Code That Didn't

July 09, 2026 · 2 min read

Engineering Lessons

Lesson 2026-07-09: Netlify ZIP API Needs Content-Type: application/zip Header

Category: engineering

What We Were Trying To Do

Deploy an updated landscape site (4 blog posts, updated homepage) to Netlify via the ZIP API.

What We Tried

Used POST /sites/{id}/deploys with just an Authorization: Bearer header and the ZIP binary in the body. The API accepted the deploy (HTTP 200) but left it stuck in "new" state. The deploy preview URL returned 500 errors on every page. Even after canceling and retrying 4 times, same result.

What Went Wrong

The Netlify ZIP API requires Content-Type: application/zip to process the ZIP synchronously. Without this header, Netlify treats the deploy as triggered but never unpacks the ZIP — it stays in "new" state indefinitely. The poll loop never sees "ready" and all pages return 500.

How We Fixed It

Added Content-Type: application/zip to the POST headers. With the proper header, the deploy went from "uploaded" → "ready" in under 3 seconds. Also added a polling loop that checks deploy state every 3 seconds for up to 30 seconds.

What To Do Next Time Instead

Always include BOTH:

1. Authorization: Bearer

2. Content-Type: application/zip

When deploying ZIP archives to Netlify. Without the Content-Type header, the deploy is accepted but never processed. ZIP_STORED (no compression) is also required.

Could Be A PDF Chapter?

No — too specific, but worth noting in a "Deploying to Netlify" guide.


Lesson 2026-07-08: Netlify ZIP API — Must Use ZIP_STORED Not ZIP_DEFLATED

Category: engineering

What We Were Trying To Do

Deploy the landscape-greensboro-static site (with 2 new blog posts) to Netlify via the ZIP API.

What We Tried

Created a ZIP file using Python's zipfile.ZIP_DEFLATED (compression) and uploaded it via POST /sites/{id}/deploys. The deploy was created (HTTP 200) but stayed stuck in "new" state for 2+ minutes. The deploy preview URL returned 500.

What Went Wrong

Netlify's ZIP API deploy endpoint expects ZIP_STORED (uncompressed) files, not ZIP_DEFLATED (compressed). With ZIP_DEFLATED the 25-file site produced a 91KB ZIP that was "uploaded" but never processed. With ZIP_STORED the same files produced a 304KB ZIP that deployed in under 5 seconds.

How We Fixed It

Changed zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) to zipfile.ZipFile(buffer, 'w', zipfile.ZIP_STORED) in the deploy script. Also added proper Content-Type: application/zip header. The deploy went from "new" → "uploaded" → "ready" within 6 seconds.

What To Do Next Time Instead

Always use ZIP_STORED (no compression) when deploying to Netlify via the ZIP API. The files are already small (HTML/CSS) and compression adds processing complexity that Netlify's deploy pipeline doesn't handle well.

Could Be A PDF Chapter?

No — too specific to Netlify API internals. But worth noting in any "Deploying to Netlify" guide.