Files and uploads
How to share large files with a client
File-upload limits, presigned-URL uploads, virus scanning, and how to handle clients who can't upload (and vice versa).
Audience: owner · 4 min read · Last reviewed
The Files section in each client portal is backed by Cloudflare R2 storage in the EU jurisdiction. Files upload through presigned URLs straight from the browser to R2, never through the application server. This is faster, cheaper, and keeps large files off your bandwidth.
Limits
- Per-file size: 5 GB. Suitable for raw video exports, large Figma masters, full design archives.
- Per-workspace storage: 1 GB included with any paid workspace. Top up with 1 GB (€3), 5 GB (€7), or 20 GB (€15) packs. Storage packs are one-off, not subscription.
- Per-file type: all file types are supported. No restriction on extension.
Uploading from the agency side
In /app/files:
- Click + Upload in the top right.
- Pick the client this file belongs to.
- Pick the folder (the configurator scaffolds default folders; you can create new ones).
- Drag the file into the upload zone, or click to browse.
- While the upload is in progress, the file shows a progress bar. The session is async; you can navigate elsewhere and come back.
The file is available to the client immediately after upload completes. The activity feed fires file.uploaded to your webhook endpoints if configured.
Uploading from the client side
The client sees the same Files panel in their portal. They click + Upload and pick their file.
For clients who're unfamiliar with file-upload UIs:
- The drop zone accepts drag-and-drop from the OS file manager.
- Click-to-browse opens the standard file picker.
- Multiple files at once work; select with shift-click in the file picker.
If a client has trouble, the most common cause is:
- Their browser blocks pop-ups for downloads (so the file picker doesn't appear). Solution: ask them to allow pop-ups for
portal.yourfirm.com. - Their corporate network blocks direct uploads to Cloudflare R2. Solution: ask them to try from a different network (home, hotspot). If that's not possible, you can email-receive the file and upload it on their behalf.
- The file is bigger than 5 GB. Solution: split the file (zip with split archives) or use a one-off WeTransfer link sent through the portal messages.
File requests (asking the client to upload)
For most workflows, you don't want the client to wander into the Files section and guess what to upload. You want them to see a specific request: "We need the Q1 bank statements by 15 January."
To create a file request:
/app/clients/<client>/files→ + Request file.- Subject: a short label ("Q1 bank statements").
- Description: what the file should contain (helps the client identify the right document).
- Folder destination: where the upload should land (e.g., "01-Bank statements").
- Deadline: when you need it by (drives the three reminder emails).
The request appears in the client's portal as a card with a drop zone. Filled requests get checked off automatically when the upload classifies as the requested type.
For the accounting use case (180-client SA onboarding), file requests scale via the template pack: one click installs the "annual self-assessment" template, which generates seven file-requests per client.
Document classification
When a client uploads a file, the system runs classification:
- Filename heuristics check first (very fast, no AI). Files named
P60-2026.pdforinvoice-001.pdfget categorised in milliseconds. - AI classifier (Claude Haiku via Kie.ai) runs on filenames the heuristics don't match. The classifier reads the filename and the first page of the PDF (if applicable), returns a category and a confidence score.
- Manual override: if the classification is wrong, click the file → Edit classification → pick the right category. Future uploads with similar filenames get biased toward your correction.
Classification accuracy in production:
- Filename heuristics: ~96% on clear filenames
- AI classifier: ~92% on ambiguous filenames
- Combined: ~95% of all uploads land in the right folder without manual intervention
The 5% that need manual correction get caught at first download attempt: if you go looking for the bank statements and they're not in the bank-statements folder, you fix it then.
Downloading
From the agency side, click any file in /app/files to download. Files preserve their original format and filename.
From the client side, same flow: click the file, download starts. Downloads happen direct from R2 via signed URLs, valid for 10 minutes from generation.
Virus scanning
All uploaded files (from either side) are scanned for malware before being made available for download. The scan happens asynchronously; a "scanning..." badge appears for up to 30 seconds after upload. If a file fails the scan, it's marked Quarantined and neither side can download. You see a notification to investigate.
If a legitimate file is flagged (rare, but happens), file a support request via contact with the file ID. We can manually clear it after review.
Deleting and replacing
To delete a file: click → Delete. Soft-delete by default (recoverable for 30 days). Hard-delete after 30 days or via Delete permanently action.
To replace a file (uploading a new version with the same name): just upload. The portal versions automatically. The client sees the latest version by default; both sides can view the version history.
Bulk operations
/app/files supports bulk download (select multiple files → Download as ZIP) and bulk delete. Bulk operations are useful at the end of an engagement when archiving the deliverable package.
What this looks like in practice
For real-world workflows:
- Agency walkthrough shows file delivery for brand design (large PDFs, source files).
- Accounting walkthrough shows bulk document collection (tax season).
- Law firm walkthrough shows KYC document collection (sensitive corporate documents).