heremyapp/docs llms.txt
View as Markdown

Static sites

A space holds one static website. Each deploy uploads the whole site as one archive and publishes it atomically.

Create a space

The slug is part of the permanent URL, so use the product's name: 1-30 characters, lowercase letters, digits and single hyphens (my-app, not My_App or my--app).

curl -sS -X POST "$API/spaces" -H "$AUTH" -H "content-type: application/json" \
  -d '{"slug":"my-app","name":"My App"}' -w '\nHTTP %{http_code}\n'
{"id":"spc_7t1v...","slug":"my-app","name":"My App","status":"active","active_deployment_id":null,
 "public_url":"https://heremyapp.com/peter/my-app","site_url":"https://peter--my-app.heremyapp.com/","created_at":"2026-10-08T06:15:13.492Z"}

409 space_exists means the space is already there: use it. GET $API/spaces lists your spaces. Share public_url; site_url is the origin it redirects to and may change.

Deploy

Put the built site in a folder with index.html at its root and send the folder as a tar.gz body:

tar -czf - -C dist . | curl -sS --fail-with-body -X POST "$API/spaces/my-app/deployments" \
  -H "$AUTH" -H "content-type: application/gzip" --data-binary @-
{"id":"dep_5adj...","space":"peter/my-app","status":"published","version":"1.0.0","build":1,"notes":null,
 "file_count":12,"total_size":845120,
 "public_url":"https://heremyapp.com/peter/my-app","site_url":"https://peter--my-app.heremyapp.com/",
 "skipped":[".DS_Store"],"stripped_prefix":null,"created_at":"2026-10-08T06:15:15.476Z",
 "advice":[{"code":"missing_terms","message":"No terms of use at /terms. ...","docs":"https://heremyapp.com/docs/legal"}]}
  • Every deploy gets the next build number and a version. Add bump (major, minor or patch) and notes to the deploy URL; see Releases and versioning. Without bump, the patch version goes up.
  • The response's advice list points out things people often miss (privacy policy, terms, link previews, page language, favicon). It never blocks a deploy; see Privacy policy and terms.
  • Publishing is atomic. A failed deploy leaves the live site untouched.
  • Redeploying keeps the same URL, and the change is visible immediately.
  • The server detects tar or tar.gz from the bytes; send content-type: application/gzip or application/x-tar.
  • If the archive wraps everything in a single folder (for example dist/), that folder is unwrapped.

File rules

  • index.html must exist at the site root.
  • Allowed extensions: html, htm, css, js, mjs, json, map, webmanifest, txt, md, xml, pdf, wasm, png, jpg, jpeg, gif, webp, avif, svg, ico, woff, woff2, ttf, otf, mp4, webm.
  • If any file has another extension, or no extension, the whole deploy fails with unsupported_file_type, and details.files lists the offending files. Remove or rename them and deploy again.
  • Installers (.pkg, .dmg, .zip) are never site files. Publish them as installers.
  • Hidden files and folders (.DS_Store, ._*, .git/) and __MACOSX/ are skipped and listed in skipped.
  • Paths with .., absolute paths, backslashes and duplicates are rejected (invalid_path, duplicate_path). Symlinks and other special files are rejected with unsupported_entry: copy the real files into the folder instead.
  • Limits: 20 MiB of files in total, 1,000 files, 25 MiB compressed upload.

How URLs map to files

The site is served at the root of its own origin, so relative (assets/app.css) and root-absolute (/assets/app.css) paths both work.

Request File served
/ index.html
/style.css style.css (exact path first)
/about about.html, otherwise about/index.html (redirects to /about/)
/about/ about/index.html
anything missing your 404.html with status 404, if it exists

Verify

curl -sIL https://heremyapp.com/ACCOUNT/my-app | grep -iE "^HTTP|^location"   # 302 to the site origin, then 200

Stage, inspect and roll back

  • Stage without publishing: add ?publish=false to the deploy URL, then publish it with POST $API/deployments/DEPLOYMENT_ID/publish.
  • GET $API/spaces/my-app/deployments lists the 50 most recent deployments, newest first. The live one has "status":"published".
  • GET $API/deployments/DEPLOYMENT_ID shows one deployment with its file list.
  • Roll back by publishing an older deployment:
curl -sS --fail-with-body -X POST "$API/deployments/OLD_DEPLOYMENT_ID/publish" -H "$AUTH"