Free static site hosting with no signup

Put a folder or a single HTML file on a public HTTPS URL with one command and no account: curl -fsSL https://chorus.host/publish.py | python3 - ./site. The site is live at https://<name>.chorus.host for 24 hours; open the claim link and sign in with an emailed code to keep it.

Updated 1 October 2026 · For agents: /guides/host-static-site-no-signup.md

The one command

Run it from the folder that holds your site (or point it at a single file):

curl -fsSL https://chorus.host/publish.py | python3 - ./site

It prints JSON like this (claim token shortened here):

{
  "url": "https://navy-twig-20.chorus.host",
  "slug": "navy-twig-20",
  "anonymous": true,
  "expiresAt": "2026-10-02T05:30:23Z",
  "files": 2,
  "claimUrl": "https://chorus.host/claim/navy-twig-20#ctk_REDACTED",
  "claimToken": "ctk_REDACTED"
}

Live at the url for 24 hours. To keep it, open the claimUrl, enter your email and the 6-digit code we send you.

Measured on 1 October 2026 (one run, two files, from a Mac in the San Francisco Bay Area): 3.0 seconds from pressing Enter to a published site, including downloading the script, and 3.4 seconds until the link answered 200.

Only have curl? One HTML file is one request:

curl -sS https://chorus.host/v1/publish -F file=@index.html

Or drop a file, a folder or a .zip here:

Links last 24 hours. Sign in (free) to keep them.

Pick a way to publish

You haveUse
A folder or a file, and Python 3curl -fsSL https://chorus.host/publish.py | python3 - ./site
One file and curl, or a zipped foldercurl -sS https://chorus.host/v1/publish -F file=@index.html (or -F archive=@site.zip)
A script or CI job publishing big foldersThe HTTP API in three calls
An agent with a shell (Claude Code, Codex, Cursor)npx skills add chorus-host/skill -g, or the one command above
An agent with no shell (claude.ai, other MCP clients)The MCP server https://chorus.host/mcp, tool publish_site (setup)
A build folder you deploy again and againbeacon deploy ./dist (the CLI)
No terminal at allThe drop zone above, or chorus.host/html-to-url

Host a static site without an account in one command

publish.py is a standard-library Python script; nothing to install. What it does:

If you have an API key in CHORUS_API_KEY, BEACON_API_KEY or ~/.config/beacon/config.json, the site goes into your account and doesn't expire. Pass --anonymous to ignore the key.

Publish from an AI agent and let a human claim it later

Agents that can run commands only need the one command above, or the skill: npx skills add chorus-host/skill -g teaches Claude Code, Codex, Cursor and Gemini CLI how to publish and what to tell you afterwards.

Agents without a shell use the MCP server. In Claude Code:

claude mcp add --transport http chorus https://chorus.host/mcp

In any client that takes a JSON config (mcp.json):

{ "mcpServers": { "chorus": { "type": "http", "url": "https://chorus.host/mcp" } } }

On claude.ai, add https://chorus.host/mcp as a custom connector. The publish_site tool takes up to 4 MB of files per call without an API key (10 MB with one) and up to 1,000 files. All clients, including ChatGPT's limits.

Paste this to your agent:

Publish this folder to chorus.host and give me the link and the claim link, exactly as returned. Instructions: https://chorus.host/skill.md

The hand-off rule the skill gives agents: show the live URL on its own line, and the claim link character for character. The code after # in the claim link is 47 characters; if an agent shortens or rewraps it, the link breaks.

The HTTP API in three calls

One request (/v1/publish) is the simple path for small sites: up to 4 MB of files without an account. The three-call API handles big sites: register the files with their sizes and SHA-256 hashes, upload each one to the URL you get back, then make the version live. The hash is what lets chorus.host skip files it already has, so re-publishing a big folder only uploads what changed. One file:

FILE=index.html
HASH="sha256:$( (shasum -a 256 "$FILE" 2>/dev/null || sha256sum "$FILE") | cut -d' ' -f1)"
SIZE=$(wc -c < "$FILE" | tr -d ' ')
curl -sS https://chorus.host/v1/sites -H "Content-Type: application/json" \
  -d '{"files":[{"path":"index.html","size":'"$SIZE"',"contentType":"text/html; charset=utf-8","hash":"'"$HASH"'"}]}' \
  > site.json
UPLOAD_URL=$(jq -r '.uploads.pending[0].uploadUrl // empty' site.json)
[ -z "$UPLOAD_URL" ] || curl -sS -X PUT "$UPLOAD_URL" \
  -H "Content-Type: text/html; charset=utf-8" --data-binary @"$FILE"
curl -sS -X POST "https://chorus.host$(jq -r .version.finalizeUrl site.json)" \
  -H "X-Claim-Token: $(jq -r .claimToken site.json)"
jq -r '"\nLive: \(.site.url)\nClaim it to keep it: \(.claimUrl)"' site.json

To choose the name, add "slug":"my-site" next to "files". Names are 3 to 63 lowercase letters, digits and hyphens.

A whole folder with curl

publish-dir.sh: the same three calls for every file in a folder (bash, curl, jq)

Save this as publish-dir.sh and run bash publish-dir.sh ./site. It sends every file in the folder (hidden files are skipped) and prints the URL. If BEACON_API_KEY is set, the site goes into your account instead of expiring.

#!/usr/bin/env bash
# publish-dir.sh DIR: publish a folder to chorus.host and print its URL.
# No account: the site lasts 24 hours. With BEACON_API_KEY set: it's yours.
# Needs curl, jq, and shasum or sha256sum. Files up to 250 MB each.
set -eo pipefail
cd "${1:?usage: publish-dir.sh DIR}"

mime() {
  case "$(printf '%s' "${1##*.}" | tr '[:upper:]' '[:lower:]')" in
    html|htm) echo "text/html; charset=utf-8" ;;
    css) echo "text/css; charset=utf-8" ;;
    js|mjs) echo "text/javascript; charset=utf-8" ;;
    json|map) echo "application/json" ;;
    txt) echo "text/plain; charset=utf-8" ;;
    csv) echo "text/csv; charset=utf-8" ;;
    xml) echo "application/xml" ;;
    svg) echo "image/svg+xml" ;;
    png) echo "image/png" ;;
    jpg|jpeg) echo "image/jpeg" ;;
    gif) echo "image/gif" ;;
    webp) echo "image/webp" ;;
    ico) echo "image/x-icon" ;;
    pdf) echo "application/pdf" ;;
    woff2) echo "font/woff2" ;;
    wasm) echo "application/wasm" ;;
    mp4) echo "video/mp4" ;;
    *) echo "application/octet-stream" ;;
  esac
}
sha256() { { shasum -a 256 "$1" 2>/dev/null || sha256sum "$1"; } | cut -d' ' -f1; }

manifest=$(find . -type f ! -path '*/.*' | sed 's|^\./||' | while IFS= read -r file; do
  jq -n --arg path "$file" --argjson size "$(wc -c < "$file" | tr -d ' ')" \
    --arg type "$(mime "$file")" --arg hash "sha256:$(sha256 "$file")" \
    '{path: $path, size: $size, contentType: $type, hash: $hash}'
done | jq -s '{files: .}')

auth=()
if [ -n "$BEACON_API_KEY" ]; then
  auth=(-H "Authorization: Bearer $BEACON_API_KEY")
fi

res=$(curl -sS --fail-with-body https://chorus.host/v1/sites "${auth[@]}" \
  -H "Content-Type: application/json" -d "$manifest")

jq -r '(.uploads.pending // [])[] | select(.uploadUrl) | [.path, .uploadUrl] | @tsv' <<<"$res" |
while IFS=$'\t' read -r file url; do
  curl -sS --fail-with-body -X PUT "$url" -H "Content-Type: $(mime "$file")" \
    --data-binary @"$file" >/dev/null
done

token=$(jq -r '.claimToken // empty' <<<"$res")
if [ -n "$token" ]; then
  auth=(-H "X-Claim-Token: $token")
fi
curl -sS --fail-with-body -X POST "https://chorus.host$(jq -r .version.finalizeUrl <<<"$res")" \
  "${auth[@]}" >/dev/null

jq -r '"Live: \(.site.url)", (.claimUrl // empty | "Claim it to keep it: \(.)")' <<<"$res"

The beacon CLI

curl -fsSL https://chorus.host/install.sh -o install-beacon.sh && sh install-beacon.sh
beacon deploy ./site --pretty

On Windows PowerShell, install with iwr https://chorus.host/install.ps1 -useb | iex and run the same beacon deploy. If the folder has a package.json with a build script, the CLI runs npm run build first and uploads dist/, build/ or out/. It saves the claim token in .beacon/state.json, so after beacon login, running beacon deploy again from the same place claims the site.

Claim the site later

Every site published without an account comes with a claimUrl like https://chorus.host/claim/navy-twig-20#ctk_....

curl -sS -X POST "https://chorus.host/v1/sites/$SLUG/claim" \
  -H "Authorization: Bearer $CHORUS_API_KEY" -H "Content-Type: application/json" \
  -d '{"claimToken":"'"$TOKEN"'"}'

Claiming removes the expiry. After that, manage the site with Authorization: Bearer instead of X-Claim-Token.

No account vs free account

No accountFree account
How long the site lasts24 hours, then it is deleted (how expiry works)Until you delete it, or an expiry you set
Publishes per hour5 per IP address60 per account
Largest file250 MB5 GB
Files per site10,00010,000
Total size per site10 GB10 GB
Password protectionYesYes
Search enginesSent X-Robots-Tag: noindex until claimedCan be indexed
Custom domainNoNo
Workers (APIs, webhooks)NoYes

Custom domains aren't available on any plan yet. Every site lives at <name>.chorus.host.

Other ways to publish without an account

Checked 1 October 2026:

Netlify Drop, tiiny.host and surge.sh compared in full, with measured times, and how chorus.host compares with here.now.

When another host fits better:

Need an API next to the site? Deploy it as a chorus.host Worker. Sharing one HTML report? Share an HTML file as a link has the password, update and expiry steps.

Good to know

Questions

Can I host a static site without an account?

Yes. curl -fsSL https://chorus.host/publish.py | python3 - ./site publishes the folder to https://<name>.chorus.host with no account. It stays up for 24 hours; open the claim link and sign in to keep it.

Is there free static hosting with no signup?

chorus.host is free with or without an account. Without one, sites last 24 hours and you can publish 5 an hour from one IP address. A free account, made with just an emailed code, keeps sites until you delete them.

What's the fastest way to put a single index.html on a public URL?

curl -sS https://chorus.host/v1/publish -F file=@index.html. One request, no account, and the response has the link.

How do I deploy a static site from the command line without signing up?

Run curl -fsSL https://chorus.host/publish.py | python3 - ./dist from your project, or install the beacon CLI and run beacon deploy ./dist. Both print the URL. Running either again updates the same site.

How long does a site published without an account stay up?

24 hours from the first publish. Updating it doesn't reset the clock. Claim it to keep it, or it is deleted and the URL stops working.

How do I claim a site later, and can my AI agent hand it to me?

Open the claim link the publish returned and sign in with your email and a 6-digit code. Agents using the chorus.host skill or MCP server are told to give you that link exactly as returned, so you can claim the site from any device.

Can I use a custom domain?

No. Every site lives at <name>.chorus.host, with or without an account. If you need your own domain, Netlify, Cloudflare Pages or here.now's free plan support one.

Is there an instant static hosting API with no signup?

Yes. POST https://chorus.host/v1/publish takes a file, a multipart form or a zip and returns the live URL in one request. For big sites, the three-call API (POST /v1/sites, upload, finalize) handles files up to 250 MB each.

Will search engines index my site?

Not while it's unclaimed: those sites are sent with X-Robots-Tag: noindex. Once claimed into an account, they can be indexed like any other site.