Groundfloor Docs
Shell apps

Files

Upload, download and delete files from a Shell app.

Your Shell app can store files in your workspace's file storage: uploads, attachments, generated reports. The browser sends the file straight to storage over a short-lived link, so large files don't pass through your app. You can see the same files in Data → Files in the Client Portal.

All requests below go to your workspace's files API with the user's token:

const files = `${window.__GF_CONTROLPLANE_URL__}/v1/workspaces/${window.__GF_WORKSPACE_ID__}/files`;
const auth = { Authorization: `Bearer ${await window.__GF_GET_ACCESS_TOKEN__()}` };

Upload a file

An upload takes three requests: ask for an upload link, send the file to it, then confirm.

async function upload(file: File) {
  // 1. Ask for an upload link
  const init = await fetch(`${files}/upload-url`, {
    method: "POST",
    headers: { ...auth, "Content-Type": "application/json" },
    body: JSON.stringify({ name: file.name, content_type: file.type, size_bytes: file.size }),
  }).then((r) => r.json());

  // 2. Send the file straight to storage
  const put = await fetch(init.upload_url, {
    method: "PUT",
    body: file,
    headers: file.type ? { "Content-Type": file.type } : undefined,
  });
  if (!put.ok) throw new Error(`Upload failed: ${put.status}`);

  // 3. Confirm, so the file becomes available
  await fetch(`${files}/${init.file.id}/finalize`, { method: "POST", headers: auth });
  return init.file.id;
}

Upload links expire after an hour. Until step 3, the file is pending and doesn't appear in lists.

Download, list and delete

ToRequest
Get a download linkGET {files}/{file_id}/download-url. Links expire after an hour
List filesGET {files} — up to 200 confirmed files, newest first
Delete a fileDELETE {files}/{file_id}

Who can do what

ActionNeeds
List files and downloadread
Uploadwrite
Deletedelete

Next steps

  • Files — manage files in the Client Portal.
  • Files API — every request and field.

On this page