Skip to content
Dashboard
Menu Deploying · Body formats

Deploying

Body formats

POST /deploy reads the Content-Type header to decide how to parse the body. Three formats cover everything from a single page to a full build folder — all three answer with the same JSON envelope described in Deploy a drop.

Raw HTML

The simplest case: the body is the page. It lands as index.html at the root of the drop. This is also the fallback — any Content-Type that isn’t JSON or zip is treated as raw HTML.

bash
curl -X POST https://hurl.page/deploy \
  -H "Content-Type: text/html" \
  --data-binary @index.html

JSON files map

For multi-file drops without an archive, send application/json with a files object. Each key becomes a path on the drop; text goes in as plain strings, binary assets as { "encoding": "base64", "content": … } objects.

bash
curl -X POST https://hurl.page/deploy \
  -H "Content-Type: application/json" \
  -d '{
    "files": {
      "index.html": "<h1>hi</h1>",
      "css/app.css": "body{}",
      "logo.png": { "encoding": "base64", "content": "iVBORw0KGgo…" }
    }
  }'

Leading slashes on paths are stripped, and paths containing .. are rejected with a 400.

Zip upload

When a build tool already produced a folder, zip it and stream the archive:

bash
curl -X POST https://hurl.page/deploy \
  -H "Content-Type: application/zip" \
  --data-binary @dist.zip

If the archive wraps everything in a single root directory (say dist/), it’s stripped automatically — your index.html still ends up at /. macOS litter (__MACOSX/, .DS_Store) is dropped too.

Archives are capped at 25 MB on the free plan and 100 MB for subscribers, and may decompress to at most 4× the cap — past either limit the deploy fails with a 413. See Limits & plans.

How files are served

Files are served with a Content-Type inferred from their extension — the usual web set (html, css, js, json, svg, png, jpg, gif, webp, ico, txt, xml, woff, woff2, pdf, wasm, map). Anything unrecognized ships as application/octet-stream.