Publish site
publish_siteUse when the user wants to put a page online, share this with a client or teammate, or get a link they can send. Publishes a document or bundle to SnapHost and returns its stable share URL. Provide exactly one of html (one document, as text), files (text files as {path, content}: a page with its CSS/JS/JSON/SVG, or one Markdown, CSV, Mermaid, notebook, code or .tsx/.jsx component file), zipBase64 (a bundle with binaries that fits the request body, an Office file, or a one-entry zip holding a PDF, image, video or audio) or upload_id from create_bundle_upload (large or binary bundles; a lone binary file with filename). html and files need no shell and no network of your own: the routes from a chat window. Each renders to a sandboxed site; an Office file shows as its page alone (no notes, hidden slides, sheets or comments) and downloads only with include_original; render_notices says what the page could not show. The content kind is detected on publish and returned as content_kind. Pass a slug to make the publish idempotent: later calls with the same slug update the same URL. Optionally set status (draft hides it until published) and an allowlist (Pro only). The result reports link_expires_at and has_view_password; manage them with set_link_expiry / set_view_password / clear_view_password. A new site lands in the publisher's own My drive, addressed on the workspace subdomain as /~/, unless folder_id (from list_folders) or space "shared" files it on the Shared drive, where it is addressed by its slug or folder path. visibility "public" opens it to anyone with the link (a landing page must be). Publish also scans the page for window.SNAPHOST data usage: a collection the page queries is set up as public_read, one it only appends to stays owner-only, and on the marketing site nothing is opened (the owner asks by name, only for records with no personal detail); the result says what was configured; relay it and confirm with the owner. The page is also scanned for external references (CDN scripts, font stylesheets, embeds) that the site's security policy will block: the result lists each blocked origin. Ask the owner whether to trust it (add_external_origins) or vendor the asset. Missing relative references are reported too; add the files and republish. Reports, decks, dashboards: pass document_kind.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| html | No | A single self-contained HTML document, as text. The first choice for one page: it needs no encoding, no shell and no network of your own. At most 3.5 MB once JSON-escaped (a control character other than backspace, tab, newline, form feed and carriage return, `<`, `>`, `&` or any non-ASCII character counts 6 bytes, an emoji 12, and `"`, `\` and `/` 2, so non-ASCII text may count three times its size and markup-heavy text up to six): in practice about 3 MB of plain HTML, about 2 MB when tag-dense; the rest of the 4 MB request body is for the call itself. A bigger page: Trim it, split it across more than one site, give the person the text to save as a file and hand it over, or send it through create_bundle_upload, which needs a shell that makes the SnapHost tool calls itself. | |
| slug | No | Slug, unique within the drive the site is filed in; reuse it with the same folder_id or space to update the same site at the same URL. For a landing page the slug IS the address under /lp: pass exactly the path you were asked for; omitted, it is derived from the title and the page lands at a different address. A slug already used by a site elsewhere on the drive is refused, and so is one that is another site’s old address (the refusal says where that site went: update it instead of publishing a second one). | |
| files | No | Plain-text files, each `{path, content}`, zipped for you: a page with its own CSS, JS, JSON or SVG files (name the entry `index.html`), or one Markdown, CSV, Mermaid, notebook, code or .tsx/.jsx React component file on its own, rendered as its kind under its path (a component needs a default export and may import only react, react-dom, recharts, lucide-react, d3, framer-motion and @radix-ui/react-*). Paths are relative to the bundle root with forward slashes (`index.html`, `assets/app.js`). Text only: an image, a font, a PDF or any binary is referenced at a URL (add_external_origins) or sent through create_bundle_upload. At most 100 entries and 2 MB of text in total (UTF-8), and 3.5 MB once JSON-escaped (a control character other than backspace, tab, newline, form feed and carriage return, `<`, `>`, `&` or any non-ASCII character counts 6 bytes, an emoji 12, and `"`, `\` and `/` 2, so non-ASCII text may count three times its size and markup-heavy text up to six): in practice about 2 MB of plain English or 1 MB of non-Latin or tag-dense text. The rest of the 4 MB request body is for the call itself. Like `html`, this works from any client, a chat window with no shell included. | |
| space | No | Drive root for a folderless site: `personal` (default, the publisher’s My drive) or `shared`. Ignored when folder_id is given. | |
| title | Yes | Title shown to the owner in the dashboard | |
| status | No | `published` (default) is live immediately; `draft` stays hidden until published | |
| filename | No | The uploaded file's own name with its extension (`report.pdf`, `photo.png`, `data.csv`). Give it once, at create_bundle_upload; a name given here as well must match it. Pass it here only for a single non-zip file whose upload was opened without one, so it is rendered as its kind; an upload that no name describes and that is neither a zip nor an HTML page is refused. For a .docx, .pptx or .xlsx sent as `zipBase64`, give its name here: it heads the bar and names the download. Ignored for a .zip bundle. A name SnapHost does not take is refused with the export that would work. | |
| allowlist | No | Emails or domains allowed to view a private site (Pro only) | |
| folder_id | No | File the new site into this folder (folder_id from list_folders). A landing page goes into the website workspace’s Marketing folder: pass that workspace’s workspace_id as well; without it the publish is refused on a connection that reaches several workspaces (and lands in the personal space on one that reaches only it), and the site is not a landing page, whatever its slug. | |
| printable | No | The page is built to print (a PDF that keeps the look): the design check asks for print styles, and a plain page gets the viewer's Print action (a report or a deck carries its own Download PDF button instead). Kept on later updates unless given again. | |
| upload_id | No | Reference a bundle already uploaded via create_bundle_upload (sent with upload_bundle_part, or PUT to its `upload_url`); use this for a large or binary-carrying app (e.g. a built React site with images and fonts) that `html` or `files` cannot hold, or for a single file that is not text (a PDF, an image, a video, an audio, a .docx, .pptx or .xlsx), sent as it is together with `filename`. Sending the bytes needs a shell that makes the SnapHost tool calls itself; without a shell the person drops the file on the dashboard: the drive (https://app.snaphost.ai/) for a new site, or the site's own page (https://app.snaphost.ai/sites/<site_id>, "Upload a new version") to keep an existing link. Mutually exclusive with `html`, `files` and `zipBase64`. | |
| zipBase64 | No | Base64-encoded .zip bundle (entry HTML + assets), for a multi-file bundle that holds binaries and fits the 4 MB request body once encoded; a .docx, .pptx or .xlsx (zips themselves) or a one-entry zip holding a single PDF, image, video or audio file under its real name also goes here. Text belongs in `html` or `files` instead: base64 has to be reproduced byte for byte and a long string often is not, so this input is rejected outright if the encoding or the archive checksums do not verify. Producing it needs a shell that makes the SnapHost tool calls itself; a client without one sends text as `files` and hands a binary to the person for the dashboard: the drive (https://app.snaphost.ai/) for a new site, or the site's own page (https://app.snaphost.ai/sites/<site_id>, "Upload a new version") to keep an existing link. | |
| visibility | No | `public`: anyone with the link (the default on Free). `allowlist` (the default on Pro): only the people on the allowlist, after verifying their email; Free may name up to 3. A landing page must be public. Applies to a NEW site only; change an existing site with set_visibility. | |
| workspace_id | No | Optional: the workspace to act in, from list_workspaces (the connection reaches the person's personal space and every workspace they are a member of). Required on a write when the connection reaches more than one workspace. Omit to act in the personal space (for an older single-workspace connection, the one workspace it was authorized for). | |
| document_kind | No | What the site is: a report, a presentation, a dashboard, or a plain page (the default). A publish or content update of such a site runs the design check (`design_warnings`); a presentation may go full screen. Kept on later updates unless given again. | |
| include_original | No | Whether readers may download the uploaded file itself from the page. Applies to a Word, PowerPoint or Excel file only, and is off by default for them, because the file holds what the page does not show: speaker notes, hidden slides, sheets, rows and columns, formulas, comments and tracked changes. Pass true to offer it anyway; on update_site, leave it out to keep the live version's choice. A macro-enabled .docm, .pptm or .xlsm is never offered. A CSV, image, video, audio, PDF, diagram or text file is its page and always downloads; a Markdown file or notebook becomes its page and has no download. The result reports `original_included`, and `render_notices` says what the page could not show (cells shown as formulas when a workbook carries no computed values; a file left out for size). Relay a notice to the user. |