API & tokens
Prefer to publish from code? Tokens let scripts, pipelines, and agents act on your account without your password. Each one is scoped, shown once, and revocable in a click.
Create a token
Open API tokens under your account settings and create a new token. Give it a name you will recognize later, then copy the value right away. For security we show it only once, so store it in your secret manager or a CI secret.
A token is yours, not a workspace’s. Over MCP it reaches your personal space and every workspace you belong to (the AI passes a workspace_id); the REST API below publishes into your personal space.
Publish a site
Send the bundle as multipart form data along with a title and visibility. The bundle field takes a .zip, a single HTML page, or a single file of any rendered kind (.md, .ipynb, .pdf, .docx, .pptx, .xlsx, .csv, .mmd, an image, a video, an audio or a text file) under its own name. The response includes the site id and its live link.
curl -X POST https://app.snaphost.ai/api/v1/sites \
-H "Authorization: Bearer $SNAPHOST_TOKEN" \
-F "title=Launch microsite" \
-F "visibility=private" \
-F "bundle=@site.zip"Update in place
Push a new bundle to the same site id and the live link stays the same. Viewers see the update on their next load, with no new link to share.
curl -X PUT https://app.snaphost.ai/api/v1/sites/$SITE_ID \
-H "Authorization: Bearer $SNAPHOST_TOKEN" \
-F "bundle=@site.zip"Large bundles
A request body is capped at a few megabytes, so a bundle with video, audio, or many images is uploaded first and published by reference. Start an upload, PUT the .zip to the returned upload_url on SnapHost itself, then publish with the upload_id. Above max_part_bytes (4 MB), split the file and PUT each piece to upload_url/parts/0, /parts/1, and so on in order. The response also carries a presigned url straight to storage, which takes the whole bundle in one request if your network can reach that host. An upload is single use and expires after 15 minutes.
# 1. Start an upload: returns upload_id, upload_url, max_part_bytes, and a presigned url
curl -X POST https://app.snaphost.ai/api/v1/uploads \
-H "Authorization: Bearer $SNAPHOST_TOKEN"
# 2. PUT the bundle to upload_url (whole, up to max_part_bytes)
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/zip" \
--data-binary @site.zip
# ...or, for a bigger bundle, as numbered parts in order
split -b 4m site.zip part-
i=0; for f in part-*; do
curl -X PUT "$UPLOAD_URL/parts/$i" -H "Content-Type: application/zip" --data-binary "@$f"
i=$((i+1))
done
# 3. Publish (or PUT /sites/:id) with the upload_id instead of a bundle file
curl -X POST https://app.snaphost.ai/api/v1/sites \
-H "Authorization: Bearer $SNAPHOST_TOKEN" \
-F "title=Launch microsite" \
-F "upload_id=$UPLOAD_ID"
# A single file that is not a zip (Markdown, a notebook, a PDF, a video, a CSV) travels the same way,
# PUT as its own bytes. Open the upload with its name so it is rendered as its kind rather than
# served as a page (or pass filename= on the publish instead):
# curl -X POST .../api/v1/uploads -H "Authorization: Bearer $SNAPHOST_TOKEN" \
# -H "Content-Type: application/json" -d '{"filename":"talk.mp4"}'
# curl -X PUT "$UPLOAD_URL" -H "Content-Type: video/mp4" --data-binary @talk.mp4
# curl -X POST .../api/v1/sites -F "title=Talk" -F "upload_id=$UPLOAD_ID"
# A Word, PowerPoint or Excel file is shown as its page alone; add -F "include_original=true"
# (on POST /sites and on PUT /sites/:id/content alike) to let readers download the file itself,
# its notes, hidden sheets, formulas, comments and tracked changes included. Both answer with
# original_included and render_notices.Keep tokens safe
Treat a token like a password. Never commit it to source control or embed it in a client. Rotate tokens on a schedule, and revoke any token immediately if it might have leaked. Revoking takes effect at once.