Skip to main content
Site files are the documentation attached to a site — plans, photos, manuals, warranties. They are the same files your team sees on the site record in the portal. All six operations live under /v1/site/{id}/file and require the scopes siteFile:read (reads) or siteFile:write (uploads and deletes). A key with site:read also has siteFile:read, and site:write also has siteFile:write.

Listing files

Pinned files come first, then the newest. Deleted files are never returned.
uploadedBy is null for files uploaded through this API — an API key is not a user, so there is nobody to attribute the upload to.

Downloading a file

GET /v1/site/{id}/file/{fileId} returns the same metadata plus a downloadUrl:
downloadUrl expires after 5 minutes. Fetch the file again for a fresh URL rather than storing or sharing the one you got — a stored URL will start returning errors.

Uploading a file

Uploads take three calls. The bytes go straight to storage rather than through this API, which is what lets them exceed the API’s 10 MB request limit. There is no single-call upload endpoint, for files of any size.
1

Ask for an upload URL

Nothing is stored yet. Keep the fileKey — step 3 needs it.
2

PUT the bytes to that URL

The Content-Type header must match the contentType you sent in step 1, or the upload is rejected. Do not send your API key to this URL. uploadUrl expires after 5 minutes; if it lapses, start again from step 1.
3

Register the file

Returns 201 with the file, which now appears in the portal. Pass "pinned": true to pin it to the top of the site’s file list.size and contentType are read back from storage, not taken from this request, so you cannot register a file that misreports either. If the upload in step 2 did not complete, this call returns 422 UPLOAD_NOT_FOUND — retry step 2 with the same uploadUrl (or start over from step 1 if it has expired), then call this again.
An abandoned upload — step 2 done, step 3 never called — is simply never registered, and the file will not appear anywhere. It is safe to retry the whole sequence.

Extracted text

Text extracted from a file has its own endpoint, so that list and get responses stay small even when a document runs to megabytes:
Expect content to be null most of the time. Text is extracted lazily — the first time someone auto-fills site documentation for that site — and only from plain-text and PDF files. Images and other formats always return null.

Deleting a file

Returns 204 with no body.
This is permanent, and matches what deleting a file in the portal does: both the file record and the stored bytes are removed. There is no undelete and no recycle bin.

Errors

A site or file belonging to another organization returns 404, not 403 — the API never confirms that a record you cannot access exists.