- Hyperclay Local
- Docs
- Serving documents
- Metadata and uploads
Metadata and uploads
Inspect host capabilities and document metadata with GET /_/meta, and upload attachments with POST /_/upload.
Documents running in Hyperclay Local discover what the host supports through GET /_/meta and upload file attachments through POST /_/upload. For how ClayJS uses these endpoints in the browser, see Host compatibility and upload and quickcrop.
GET /_/meta#
GET /_/meta returns the capabilities of the local server and, when a Document-URL (or Page-URL) header names a document that exists on disk, the metadata and limits for that document:
GET /_/meta
Document-URL: http://localhost:4321/index.html
{
"spec": 1,
"extensions": ["conditional", "format", "sync", "upload", "live-data", "live-provenance"],
"document": {
"etag": "…",
"writable": true,
"maxBytes": 20971520,
"upload": { "allowed": true, "maxBytes": 26214400 }
}
}
extensions: Announces supported host capabilities, including"conditional"(conditional saves and save receipts),"format"(formathtml="true"support),"sync"(tab live sync),"upload"(attachment uploads),"live-data", and"live-provenance".document: Included only whenDocument-URL(orPage-URL) names an existing file. If no header is sent or the named document does not exist, thedocumentkey is omitted.document.saveId: Included when the current bytes on disk were written by a save that carried aSave-IDheader (see Saving and stale-write protection).document.people.me: Included when Use my profile in files is turned on under Options then Profile…, returning your Hyperclay account profile (cached for offline use) or your local display name. This field is answered only to requests from the folder’s own origin (see Settings and profile).
POST /_/upload#
POST /_/upload stores an attachment file in the folder’s uploads/ directory instead of embedding it as a data: URL inside the HTML document. Send a multipart/form-data request with one part named file and a Document-URL header:
curl -X POST http://localhost:4321/_/upload \
-H 'Document-URL: http://localhost:4321/index.html' \
-F 'file=@note.txt'
{
"msg": "Uploaded",
"msgType": "success",
"uploads": [
{
"name": "note-2cf24d.txt",
"url": "/_/uploads/assets-index/note-2cf24d.txt",
"bytes": 5
}
]
}
Where uploads are stored and linked#
- Directory layout: Files are stored in
uploads/assets-<document stem>/inside the served folder and linked as/_/uploads/assets-<document stem>/<filename>, matching the layout used on hyperclay.com so a synced folder stays byte-identical on both sides and moving a document does not strand its files. Uploads into a folder with no document land in that folder’suploads/assets-<stem>/directory and keep their/_/uploads/link. - Content-addressed filenames: The stored filename is
<stem>-<first 6 hex of the sha256 of the bytes><ext>. Uploading identical bytes converges on the same file, while different bytes never collide (the hash prefix lengthens automatically if a 6-character prefix would collide). Characters that Windows cannot store (< > : " | ? *and control characters) are stripped from upload names so filenames work across macOS, Windows, Linux, and hyperclay.com. - URL encoding and serving:
urlin the JSON response is percent-encoded for every byte outside the unreserved set and can be placed directly intosrcorhref. The/_/uploads/route serves only files inside the realuploads/folder (refusing symlinks out of the folder) and sendsX-Content-Type-Options: nosniffon every response. - Zip export: When you export a document with Export a File as Zip…,
/_/uploads/links are rewritten to relativeuploads/…paths and packaged alongside the document (see Export as zip).
Limits, refused file types, and error codes#
- Maximum file size:
26214400bytes (25MB). A file larger than25MB is refused with413and"code":"too-large". (When cloud sync is enabled, attachments larger than your hyperclay.com plan’s per-file cap are still saved locally and served onlocalhost, but stay on your computer until your plan limit allows them; see What syncs.) - Refused extensions: Web-page and executable script types are refused:
.html,.htm,.xhtml,.htmlclay,.js,.mjs,.cjs,.xml,.xht,.xsl, and.xslt. Uploading any of these returns415:If a web-page file type is placed inside{"msg":"That kind of file cannot be uploaded.","msgType":"error","code":"unsupported-type"}uploads/on disk by hand,/_/uploads/serves it as a download withnosniffso it cannot execute script on the app’s origin. - SVG files:
.svgand.svgzfiles are allowed because/_/uploads/and the static file server serve them inert withContent-Disposition: attachmentandX-Content-Type-Options: nosniff. - Target document check: When
Document-URLnames a document path, that document must already exist; otherwisePOST /_/uploadreturns404with"code":"not-found". - Error
codevalues:bad-request,forbidden,not-found,conflict,too-large, andunsupported-type.