The short version
Snapy's publish endpoint takes a JSON POST and returns a link. Here it is with fetch.
const res = await fetch("https://api.snapy.host/api/publish", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
content: "<!doctype html><h1>Hello from JavaScript</h1>",
name: "my-page", // optional
filename: "index.html", // optional
}),
});
const data = await res.json();
console.log(data.url); // https://my-page.snapy.page
Publishing a binary file
Read the file, base64 encode it, and send it as content_base64:
import { readFileSync } from "node:fs";
const b64 = readFileSync("report.pdf").toString("base64");
const res = await fetch("https://api.snapy.host/api/publish", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ content_base64: b64, filename: "report.pdf" }),
});
console.log((await res.json()).url);
What you get back
The response includes url (the live link), stats_url (your private analytics page), and token. The url is ready to open or share. The stats_url shows views privately, and the token lets you manage the link later.
const data = await res.json();
console.log(data.url); // the public link
console.log(data.stats_url); // your private analytics page
console.log(data.token); // keep this to manage the link
Naming the link
Pass a name to choose the subdomain. If the name is free you get name.snapy.page. If it is taken the request fails, so either pick another name or omit name to let Snapy assign a random one. Add a filename (like index.html or report.pdf) when you want Snapy to treat the content as that file type.
A small helper
Wrapping the call in a function keeps scripts tidy:
async function publish(content, name) {
const res = await fetch("https://api.snapy.host/api/publish", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ content, name, filename: "index.html" }),
});
if (!res.ok) throw new Error("publish failed: " + res.status);
return (await res.json()).url;
}
const link = await publish("<!doctype html><h1>Hi</h1>", "demo");
console.log(link);
Common uses
- Publishing the HTML output of a build script or generator as a live preview link.
- Turning an AI agent's response into a hosted page and returning the link in chat.
- Posting a generated report to a link from a Node cron job, then sending that link to Slack or email.
- Sharing a single-file demo or widget straight from a script.
- Hosting an exported PDF or image from a Node tool by base64 encoding it.
Snapy serves static files. Self-contained HTML, CSS, and client-side JavaScript run fine. Anything needing a live server or a database does not, so publish finished static output rather than an app that expects a backend.
Troubleshooting
- No
urlin the response. Make sure you set thecontent-type: application/jsonheader and that the body is valid JSON. Without the header the API may not parse the body. - Publishing a binary file. Do not put binary data in
content. Base64 encode the bytes and send them ascontent_base64with a matchingfilename, as shown above. namerejected. That subdomain is taken. Choose another name or omitnamefor a random one.- Browser CORS or exposed requests. The call works from the browser, but running it client-side exposes the request to your users. Prefer running it server-side in Node when that matters.
Updating and managing a link
The token in the response is your handle for a link once it is live. Store it next to the url if a later step needs to manage the page, and treat it like a secret, since anyone with the token can manage that link:
const data = await res.json();
const record = { url: data.url, stats_url: data.stats_url, token: data.token };
// save record somewhere for later reference
To keep a stable address across repeated publishes, send the same name each time. The link stays predictable, so you always know where the latest version lives.
Working inside an app or agent
The call is plain HTTP, so it fits anywhere fetch runs: an Express route, a serverless function, a build script, or an LLM tool. A common agent pattern is to have the model write HTML, publish it, and return the url so the user gets a real link instead of raw code. With no key to manage, the whole integration stays a single request. Run it server-side when you do not want the request exposed to end users.
Good to know
- Up to 100MB per file, with fair-use rate limits.
- Same endpoint AI agents use. See the developer docs, the Python guide, or browse all integrations. To host a built frontend, see host a React app.
A few lines of fetch turn any string into a link you can share.
