Share an HTML file or report as a link

Turn report.html into a link like https://bright-river-42.chorus.host with one curl request. It opens as a web page, not a download. No account needed; the link lasts 24 hours unless you keep it, and you can add a password for free.

Updated 1 October 2026 · For agents: /guides/share-html-file-as-link.md

Share an HTML file with one command

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

That's the whole thing. A single HTML file is published as the site's home page, whatever it was called, so the link opens the report itself. Two other ways to send the same file:

# raw body instead of a form
curl -sS https://chorus.host/v1/publish -H 'Content-Type: text/html' --data-binary @report.html

# just the link on stdout (handy in scripts)
curl -sS https://chorus.host/v1/publish -H 'Accept: text/plain' -F file=@report.html

Want a name instead of a random one? Add -F slug=q3-report and the link is https://q3-report.chorus.host.

If your report links to local files (images, a CSV, a script), send them in the same request: repeat -F file=@... once per file, or zip the folder and send -F archive=@report.zip. Charts, fonts and styles loaded from a CDN work as they are.

No terminal? Drop the file on chorus.host/html-to-url or paste the HTML there.

What you get back

{
  "url": "https://q3-report.chorus.host",
  "pageUrl": "https://q3-report.chorus.host/",
  "fileUrl": "https://q3-report.chorus.host/",
  "slug": "q3-report",
  "updated": false,
  "anonymous": true,
  "expiresAt": "2026-10-02T09:14:03Z",
  "claimUrl": "https://chorus.host/claim/q3-report#ctk_REDACTED",
  "claimToken": "ctk_REDACTED",
  "passwordProtected": false,
  "versionId": "01a0f5f1-41bc-79e6-b254-af0bb753695e",
  "fileCount": 1,
  "totalBytes": 182044
}
FieldWhat it's for
urlThe link to share.
claimUrlOpen it and sign in with your email to keep the report past 24 hours. Treat it like a password: whoever has it can take the site.
claimTokenLets you update, password-protect or delete the report later. Keep it with the file; never put it on the page.
expiresAtWhen the report is deleted if nobody claims it.

Reports published without an account are sent with X-Robots-Tag: noindex, so search engines don't list them.

Opens in the browser, not as a download

Plenty of places will store an HTML file and hand back a link that shows the source code or downloads the file. That happens when the server sends it as text/plain or with Content-Disposition: attachment, or when the file isn't the page the link points at.

chorus.host serves .html as text/html; charset=utf-8, never adds Content-Disposition, and makes a lone HTML file the home page. Check any link with:

curl -sI https://q3-report.chorus.host | grep -i content-type
# content-type: text/html; charset=utf-8

Put a password on it

Free, even without an account. Add a username and password to the same request:

curl -sS https://chorus.host/v1/publish -F file=@report.html \
  -F username=team -F password='choose-a-password'

Or lock a report you already published, using its claim token:

curl -sS -X PUT https://chorus.host/v1/sites/q3-report/password \
  -H "X-Claim-Token: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"username":"team","password":"choose-a-password"}'

Visitors get the browser's login prompt before any byte of the report is sent. More detail, and how this compares with other hosts: password-protect an HTML page.

Send the new file to the same slug with the claim token:

curl -sS "https://chorus.host/v1/publish?slug=q3-report" \
  -H "X-Claim-Token: $TOKEN" -F file=@report.html

The link stays the same. Earlier versions are kept, and POST /v1/sites/<slug>/versions/<versionId>/rollback brings one back. Updating doesn't reset the 24-hour clock on a report without an account.

Keep it, or have it expire on purpose

How expiry works: temporary website hosting.

Take it down

curl -sS -X DELETE https://chorus.host/v1/sites/q3-report -H "X-Claim-Token: $TOKEN"

For a report in your account, send Authorization: Bearer $CHORUS_API_KEY instead of X-Claim-Token. The link returns 404 right away.

Large files, folders and CI: the three-call API

/v1/publish takes up to 4 MB of files per request without an account (10 MB with an API key). For bigger reports, or a pipeline that uploads only what changed, use the three-call API: register the files with their sizes and SHA-256 hashes, upload each one to the URL you get back, then finalize. It takes files up to 250 MB each without an account.

The three calls for one file
FILE=report.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

The hash is what lets chorus.host skip files it already has, so re-publishing a big folder only uploads what changed. Folders: curl -fsSL https://chorus.host/publish.py | python3 - ./report-folder does all three calls for you.

Measured

On 1 October 2026 we published a 180 KB report five times with the three-call API from a Mac in the San Francisco Bay Area. The median time from the first request to the link answering 200 text/html was 2.1 seconds. The one-request endpoint does the same work on the server, in one round trip from your side.

Other ways to share one HTML file

Checked 1 October 2026 against each service's own docs and pricing pages. Plans change; follow the source links before you rely on a cell.

Account to publishFrom a scriptLink without payingPassword on the free planOpens as a page
chorus.hostNoOne request24 hours, or until you delete it once claimedYesYes
Netlify DropNonetlify deploy --allow-anonymousRemoved after 1 hour unless claimed; until claimed it sits behind a temporary passwordNo: site passwords need ProYes
GitHub PagesYesgit push to a Pages repoPermanentNoYes
tiiny.hostYes (email sign-up)API on paid plansWhile you log in at least every 3 monthsNo: from the Solo planYes
surge.shYes (created in the terminal on first run)surge ./site publishPermanentNo: Surge ProfessionalYes

Where the others fit better: GitHub Pages keeps a free site up indefinitely and versions it in git. Netlify gives you a custom domain and a full build pipeline once you claim the site. tiiny.host has an editor, analytics and QR codes on its paid plans. chorus.host is built for the moment a script or an agent needs a working link with no account.

Let the agent do it

Paste this into Claude Code, Codex, Cursor or any agent that can run commands:

Publish report.html to chorus.host and give me the link and the claim link. Instructions: https://chorus.host/skill.md

Agents without a shell (claude.ai, Cursor's chat, other MCP clients) can use the MCP server instead: claude mcp add --transport http chorus https://chorus.host/mcp. Setup for every client is on chorus.host/mcp.

Questions

Run curl -sS https://chorus.host/v1/publish -F file=@report.html. You get back https://<name>.chorus.host, which opens the file as a page. No account needed; the link lasts 24 hours unless you claim it.

Yes. curl -sS https://chorus.host/v1/publish -F file=@report.html is one request and returns JSON with the link. Add -H 'Accept: text/plain' to get only the link.

Yes. Ask it to publish the report to chorus.host and point it at https://chorus.host/skill.md, or add the MCP server at https://chorus.host/mcp. It returns the link and a claim link you can open to keep the report.

It opens the page. HTML is served as text/html with no download header, and a single HTML file becomes the home page of the link.

Who can see it, and will Google index it?

Anyone with the link, unless you add a password. Reports published without an account are sent with X-Robots-Tag: noindex, so search engines leave them out.

24 hours without an account. Open the claim link and sign in to keep it, or publish with an API key and choose any expiry, including none.