Publish a static site with one request
The Fylo.Host API turns an HTML document into a live website at your-name.fylo.dev, served from Cloudflare’s edge in 330+ cities. JSON in, JSON out, a Bearer key in the header. Built for scripts, CI and AI agents.
Quickstart
Create a key in the dashboard (API tab), then:
# publish
curl -s https://fylo.host/api/v1/sites \
-H "Authorization: Bearer fylo_live_..." \
-H "Content-Type: application/json" \
-d '{"html":"<!doctype html><h1>Hello</h1>","subdomain":"hello-world"}'
# → 201
{ "id": "NEtS3W8axVbi2aig72Jbt", "subdomain": "hello-world",
"url": "https://hello-world.fylo.dev", "status": "active", ... }
The page is live at that URL before the response arrives. Anyone can open it; no account, no app.
Authentication
Every request needs an API key in the Authorization header:
Authorization: Bearer fylo_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keys are tied to your account and act with its plan and project limits. They are shown once when created and stored hashed; revoking one takes effect immediately. Keep keys in environment variables or a secrets manager, never in a file you publish.
For AI agents
If you are using Claude Code, Codex, Cursor or any agent that reads skills, install the Fylo skill once and then just say “publish this to Fylo”:
npx skills add raviblogger/fylo-host-skill --skill fylo -g
export FYLO_API_KEY=fylo_live_...
The skill knows how to inline assets, pick a subdomain, remember the site id in .fylo.json and update the same URL on the next publish. Source: github.com/raviblogger/fylo-host-skill. Machine-readable summary of this page: /llms.txt.
Skip the copy-paste. Tell your agent to publish it.
If you build in a coding agent, paste this once and it installs the Fylo skill, asks you for a key and puts the page on a live URL.
If the Fylo skill is not installed, install it first: npx skills add raviblogger/fylo-host-skill --skill fylo -g
Use my FYLO_API_KEY environment variable; if it is not set, ask me for a key from https://fylo.host/dashboard/api
Publish index.html as one self-contained HTML file (inline CSS and JS) to POST https://fylo.host/api/v1/sites and save the returned id in .fylo.json so future publishes update the same site.
Endpoints
Base URL https://fylo.host/api/v1. All bodies are application/json.
/meReturns the account behind the key. Handy to verify a key.
{ "id": "dkeV...", "email": "you@example.com", "name": "You", "plan": "pro" }
/sitesLists up to 100 of the account’s sites, newest first.
{ "sites": [ { "id", "subdomain", "url", "status", "created_at" }, ... ] }
/sitesCreates a site from one HTML document.
| Field | Type | Notes |
|---|---|---|
html | string | Required. A complete HTML document, up to 10 MB. CSS and JS inline; images as https:// URLs or data URIs. |
subdomain | string | Optional. 1–40 lowercase letters, digits, hyphens. Omit to get one generated. |
files | array | Instead of html: [{ "path": "index.html", "content": "<!doctype html>..." }, { "path": "css/app.css", "content": "..." }, { "path": "img/logo.png", "content": "iVBOR...", "encoding": "base64" }]. Text files as strings, binaries as base64. Must include at least one .html; index.html becomes the entry page. Up to 2,000 files and 20 MB per request. |
Returns 201 with the site object plus expires_at (always null for API publishes — they belong to your account and stay up).
files instead of html. Relative links between your files work as they would on any host. For sites over 20 MB, upload a ZIP from the homepage or dashboard./sites/:idReturns one site.
/sites/:idReplaces the site’s content. Same body as create: html for a single page (all plans), or files to replace the whole site (paid plans; the free plan gets 402 plan_limit and can use html). The URL stays the same and the edge cache is rebuilt for you. Prefer this over creating a new site for every change — each new site uses a project slot on your plan.
curl -s -X PUT https://fylo.host/api/v1/sites/NEtS3W8axVbi2aig72Jbt \
-H "Authorization: Bearer fylo_live_..." \
-H "Content-Type: application/json" \
-d '{"html":"<!doctype html><h1>Hello, v2</h1>"}'
Errors
Every error is { "error": { "code", "message" } } with a matching HTTP status.
| Status | code | Meaning |
|---|---|---|
| 401 | unauthenticated | Key missing, malformed or revoked. |
| 400 | missing_html / invalid_subdomain | Body is missing html, or the slug breaks the rule. |
| 409 | subdomain_taken | Pick another slug or omit it. |
| 402 | plan_limit | Project limit for the account’s plan reached. Update an existing site, delete one, or upgrade. |
| 413 | too_large | html over 10 MB. |
| 429 | rate_limited | Over 30 requests per minute on this key. Retry after 60 s. |
| 400 | invalid_path / duplicate_path / invalid_content | A files entry has a bad path (no .., no leading slash), repeats a path, or has non-string / bad base64 content. |
| 422 | rejected | A file was blocked by content moderation (executables, pirated-media names). |
| 502 | partial_publish | The site was created with its entry page but attaching the other files failed; the response includes site. Retry with PUT /sites/:id. |
| 404 | not_found | Unknown endpoint or a site that isn’t yours. |
Limits
- 30 requests per minute per key.
- Up to 5 active keys per account.
- Site count and storage follow your plan — see pricing. Free accounts get 1 site and 10 MB.
- The API is served only on
fylo.host; it is never exposed on hosted sites’ domains.
Managing keys
Create, list and revoke keys from the dashboardfrom the dashboard (Settings → API keys)rsquo;s API tab. The same actions are available to a logged-in browser session at GET/POST /api/keys and DELETE /api/keys/:id; these endpoints use your session cookie, not a Bearer key.
Ready to script it?
Create a key, run the quickstart, and your first page is live in under a minute.
Get an API key