spawn.page API and dashboard reference.
Publish static files, keep the token safe, bind a page when you want dashboard controls.
Quickstart
Publish any HTML file from a terminal:
curl -F "file=@index.html" https://spawn.page/publish
The response includes a public URL, a project_token, the expiry timestamp, and a bind URL. The URL is live worldwide in under a second.
If you're inside Claude, ChatGPT, Cursor, or Gemini, paste the prompt from the home page into persistent memory. After that, "publish this" should reach this endpoint without another lookup.
Auth and the project token
There is no signup and no API key. Every page gets one secret: a project_token shaped like spwn_v1_<43 base64url chars>. The token appears once, in the publish response.
Authenticated calls pass it as a bearer header:
Authorization: Bearer spwn_v1_…
Rules of the road:
- The token is the ownership credential. Whoever holds it can update or delete the page.
- Never embed the token in HTML, JS, or any file you upload.
- Store it server-side or in a local file with
chmod 600. - If it leaks, rotate immediately. The old token dies the moment the new one is issued.
POST /publish
One endpoint mints a slug, stores your files, and returns a URL.
POST https://spawn.page/publish
Content-Type: multipart/form-data
# single file
-F "file=@index.html"
# multiple files (repeat -F per file)
-F "file=@index.html"
-F "file=@style.css"
-F "file=@app.js"
-F "file=@img/logo.svg"
# zip (we unpack on the edge)
-F "file=@site.zip"
Response:
{
"url": "https://<slug>.spawn.page",
"project_token": "spwn_v1_…",
"expires_at": "2026-08-14T14:32:09Z",
"bind_url": "https://spawn.page/v1/pages/<slug>/bind",
"files": ["index.html", "style.css", "app.js"]
}
PUT and per-file edits
Full re-publish
Use the same multi-file or zip rules as /publish. The slug, URL, and token stay the same. The new upload replaces the previous content as one version. Free keeps the last three versions.
curl -X PUT \
-H "Authorization: Bearer spwn_v1_…" \
-F "file=@index.html" \
-F "file=@style.css" \
https://spawn.page/v1/pages/<slug>
Replace one file
For a single asset change, target the path directly. The rest of the project stays untouched.
curl -X PUT \
-H "Authorization: Bearer spwn_v1_…" \
-F "file=@style.css" \
https://spawn.page/v1/pages/<slug>/files/style.css
List or delete files
GET /v1/pages/<slug>/files
DELETE /v1/pages/<slug>/files/<path>
GET /files returns the path and byte size of every stored asset. DELETE /files/<path> removes one file. The page stays live for the rest.
Files, paths, and the missing-index case
We serve the folder structure you upload. Relative paths inside your HTML keep working without rewrites.
/serves/index.html./about/serves/about/index.html./img/logo.svgserves the file at that exact path.
What if there's no index.html?
- Exactly one file uploaded. We promote it to the root. So uploading
resume.pdfalone makeshttps://spawn.page/<slug>serve that PDF. - Multiple files, no index. We generate a small directory page at the root listing each file with its size. Every file is also reachable at its own path. Upload your own
index.htmlto replace it. - You don't want a public root. Upload a 1-byte
index.htmlthat returns 404, or block crawlers vianoindexheaders. Pro plans can password-protect the whole page.
MIME types are inferred from the extension. We set Content-Type for HTML, CSS, JS/MJS, JSON, XML, SVG, PNG, JPG, GIF, WEBP, AVIF, ICO, WOFF/WOFF2, TTF/OTF, MP3, MP4, WEBM, OGG, PDF, TXT, MD, CSV. Anything else is served as application/octet-stream.
Binding to an email
Binding is free and adds the page to your dashboard. It does not extend the 90-day timer on its own.
curl -X POST \
-H "Authorization: Bearer spwn_v1_…" \
-F "email=you@yours.com" \
https://spawn.page/v1/pages/<slug>/bind
We send a magic link. Click it once and the page joins your dashboard. From the dashboard you can rotate tokens, see version history, flip indexability on, or upgrade to Pro.
Rotating the token
If you suspect the token has leaked, rotate it. The old token stops working the instant the new one is minted.
curl -X POST \
-H "Authorization: Bearer spwn_v1_…" \
https://spawn.page/v1/pages/<slug>/rotate-token
# → { "project_token": "spwn_v1_…new…" }
Custom domains
Pro pages can provision one custom hostname through Cloudflare for SaaS. The endpoint returns the customer DNS target plus Cloudflare ownership and certificate-validation records while the certificate is pending.
curl -X POST \
-H "Authorization: Bearer spwn_v1_…" \
-F "hostname=docs.example.com" \
https://spawn.page/v1/pages/<slug>/custom-domain
curl -H "Authorization: Bearer spwn_v1_…" \
https://spawn.page/v1/pages/<slug>/custom-domain
curl -X DELETE \
-H "Authorization: Bearer spwn_v1_…" \
https://spawn.page/v1/pages/<slug>/custom-domain
Use a CNAME for subdomains such as docs.example.com. Apex domains need DNS-provider support for ALIAS, ANAME, or CNAME flattening to the returned target. Vanity *.spawn.page names use the vanity-subdomain endpoint instead.
Password protection
Pro pages can require a visitor password before any uploaded file is served. The project token can set, replace, or remove the password. We store a salted hash, not the password itself.
curl -X POST \
-H "Authorization: Bearer spwn_v1_…" \
-F "password=correct horse battery staple" \
https://spawn.page/v1/pages/<slug>/password
curl -X DELETE \
-H "Authorization: Bearer spwn_v1_…" \
https://spawn.page/v1/pages/<slug>/password
Visitors unlock with a browser form and receive a short-lived signed cookie. Changing the password invalidates older unlock cookies.
Auto-delete
Pro pages can schedule their own retirement. Date-only values delete after that UTC day ends; RFC3339 timestamps delete after that exact instant.
curl -X POST \
-H "Authorization: Bearer spwn_v1_…" \
-F "scheduled_delete_at=2099-01-31" \
https://spawn.page/v1/pages/<slug>/scheduled-delete
curl -X DELETE \
-H "Authorization: Bearer spwn_v1_…" \
https://spawn.page/v1/pages/<slug>/scheduled-delete
Clearing an existing auto-delete date is allowed even if the page later downgrades, so owners are not trapped behind a destructive schedule.
Deleting a page
Deletion is final. The slug is retired forever and never re-issued. There is no "trash" to restore from.
curl -X DELETE \
-H "Authorization: Bearer spwn_v1_…" \
https://spawn.page/v1/pages/<slug>
Limits and accepted file types
Free
- 2 MB for
index.html - 10 MB per file
- 100 MB total per page (all files combined)
- 3 sites per IP / account
- 1 GB bandwidth per month, per account
- spawn.page subdomain only (custom domains are Pro)
Pro ($9/mo)
- 5 MB for
index.html - 25 MB per file
- 5 GB total per page
- Unlimited sites
- 50 GB bandwidth per month
- Custom domains, vanity subdomains, password protection, auto-delete, geo rules, sitemap.xml, indexable pages
Blocked file types
Anything that runs server-side or executes natively is rejected at upload time:
.exe .dll .so .sh .bat .cmd .ps1
.php .py .rb .jar .war .ear .class
.msi .dmg .app .pkg .deb .rpm .apk
.bin .o .out
JavaScript and WebAssembly run in the browser, so SPAs, dashboards, in-browser tools, and WASM apps work. Forms that need a backend can post to an external API or webhook host. spawn.page does not run code on its servers.
Lifetime, TTL, and the 90-day rule
- Every Free page has a 90-day idle timer. Any visit, re-publish, or per-file edit resets it to zero.
- The 90-day rule applies to bound and unbound pages alike. Binding only changes who gets the warning email, not the timer.
- On day 83, bound owners get a warning email. Unbound pages get no warning.
- On day 90, the slug is retired permanently. Slugs are never re-issued.
- Pro pages have no idle timer. Pro owners can set an explicit auto-delete date.
Dashboard
The dashboard appears the moment you bind a page to an email. Inside, per page:
- Current URL, last-published time, and total visits this month.
- TTL countdown for Free pages.
- Version history with one-click rollback (last 3 on Free, unlimited on Pro).
- Rotate token. Bind/unbind email. Flip indexability. Upgrade to Pro.
- Custom domain setup (Pro), password protection (Pro), auto-delete (Pro), geo rules (Pro).
- Delete page. Final and irreversible.
Account-level controls live under a single Settings page: billing, plan, default visibility, API audit log, and account deletion.
Errors and status codes
| Status | When |
|---|---|
200 | Successful read or update. |
201 | New page created. |
204 | Successful delete. |
400 | Missing file, bad email, bad path, malformed multipart. |
401 | Missing or wrong Authorization. |
403 | Blocked file type, or operation not allowed on a retired slug. |
404 | Slug or file not found. |
409 | ETag mismatch on a conditional PUT. |
410 | Slug retired (Free TTL elapsed, auto-delete ran, or owner deleted). |
413 | File or project exceeds size limit. |
429 | Rate-limited. Backoff is returned in Retry-After. |
5xx | Our problem. Retry with exponential backoff. Status at /status. |
Discovery for agents
If an agent fetches https://spawn.page/ with no other context, these signals point at the API:
/llms.txt: the agent doc to paste into persistent memory./.well-known/spawn-api: JSON for endpoints, limits, and blocked file types.<meta name="ai-agent-instructions">in every page head, with a one-line publish recipe.
Save the prompt once in your agent's global setting. Future publish requests can go straight to the API.