API ReferenceGET /v1/sites/:id/export

GET /v1/sites/:id/export

Download the deployed site as a ZIP. Every .html page, images/, favicons, manifest, sitemap — the full bundle a static host needs.

The endpoint backs the marketing-site FAQ promise: “The generated site is yours: code, content, design. Export the source as a ZIP anytime if you want to host it elsewhere.”

Cost: Free.

Rate limit: 10 exports per site per UTC day. Exceeding the cap returns 429 with quota.resetDescription.

Request

curl -L https://api.warpweb.ai/v1/sites/8f3c2a1b-5d47-4c9e-b820-1f8a3e7d9c4f/export \
  -H "Authorization: Bearer wwk_<your-key>" \
  -o site.zip

Query params

NameTypeDefaultDescription
include_assetsbooleantrueWhen false, ships only .html files (no images/, no favicons, no manifest). Smaller archive — only useful when you want to extract copy + structure. HTML references images via relative paths, so HTML-only exports render with broken images on file://.

Response

200 OK with:

  • Content-Type: application/zip
  • Content-Disposition: attachment; filename="<slug>.zip"
  • Body is a streaming ZIP (zlib level 6).

Archive contents

PathNotes
index.html, services.html, …One file per generated page. Relative URLs only — paths like images/foo.jpg, NOT absolute /data/sites/....
images/Every image bundled with the site: uploaded photos, Google Places photos (after the photo-cascade picked them), favicon source images.
favicon.ico, apple-touch-icon.png, favicon-*.pngFavicon family per the favicon-generation pipeline.
site.webmanifestPWA manifest.
robots.txt, sitemap.xmlSEO basics.

What’s NOT included

  • revisions.json — Warpweb-internal revision log; surfaces in the dashboard instead.
  • Hidden files (.DS_Store, dotfiles).
  • Files outside the site directory — the export refuses to follow symlinks or path-traversal entries (defense-in-depth).

Errors

StatusBodyCause
404{ "error": "Site not found" }No site with that ID belongs to your account. Same shape for not-found and not-owned (we don’t leak existence).
409{ "error": "Site is not yet deployed — export available once status is complete.", "status": "generating" }Build hasn’t reached a deployed terminal state yet. Wait for status: complete or complete_with_warnings.
422{ "error": "Site has no slug — nothing to export." }Pathological row state. Contact support.
429{ "error": "Export rate limit exceeded (10/day per site)...", "quota": { "used": 10, "limit": 10, "resetDescription": "resets at midnight UTC" } }You’ve hit the per-site daily cap. Surface quota.resetDescription in your UI. Retry-After header lists the seconds-until-reset.
500{ "error": "Export failed", "detail": "..." }Unexpected server error. Safe to retry.

See Error shapes for the canonical envelope across endpoints.

Verifying the bundle

unzip -l site.zip               # list contents
unzip site.zip -d ./my-site     # extract
open ./my-site/index.html       # render from file:// — relative paths should resolve

If index.html renders with broken images from file://, the export is broken — file a bug with the archive attached. Working bundles render identically to the deployed site (minus the .pages.dev / custom-domain origin, which doesn’t matter for static hosts).

Hosting elsewhere

The bundle is plain static HTML + assets. Any static host works:

  • Netlify / Vercel / Cloudflare Pages — drag-and-drop deploy the unzipped directory.
  • GitHub Pages — commit the directory to a gh-pages branch.
  • S3 + CloudFront — sync to a bucket configured for static website hosting.
  • Self-hosted nginx / Caddy — point a vhost at the directory.

Form submissions on the exported site will NOT route through Warpweb anymore — the form’s action attribute targets /v1/webhooks/form-submit which only works for sites we’re hosting. Update the form handlers if you need form data after export.