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
| To | Request |
|---|---|
| Get a download link | GET {files}/{file_id}/download-url. Links expire after an hour |
| List files | GET {files} — up to 200 confirmed files, newest first |
| Delete a file | DELETE {files}/{file_id} |
Who can do what
| Action | Needs |
|---|---|
| List files and download | read |
| Upload | write |
| Delete | delete |