Attach files to a contact or company
BusinessUpload PDFs, Word docs, Excel spreadsheets, images, and ZIP archives to any customer or company. On the customer page, you see their files AND their company's files side by side, so the operator never has to navigate away to find a related doc.
Why files live where they do
RadiusOS is a contact-led CRM. Every job, deal, listing, or session attaches to a single customer record. We deliberately don't have a separate Project entity because most operators in trades, real estate, and small-business B2B map 1 customer = 1 work unit.
Files follow the same shape, with one extension: a file can be attached to a contact OR a company, and the contact page shows BOTH groups in one drill-down view. That means the master service agreement you signed once with a customer's company shows up on every contact at that company, with no duplication.
Where it appears
| Surface | What you see | What you can do |
|---|---|---|
| Contact detail > Files tab | Two groups: 'This customer' and (when set) 'From {company name}' | Upload files to either the contact or the company via a scope toggle |
| Company detail > Files tab | Single group: company-level files only | Upload files to the company |
| Contact has no company | Just the contact's files | Upload to the contact |
Per-contact files don't aggregate up to the company page. A big company with 8 contacts × 6 files each would be too noisy. Stay on the contact page to see that mix.
Supported file types
The picker accepts a curated list of business-relevant types. Anything outside this list is rejected at upload time with a clear error.
- PDF (.pdf)
- Microsoft Word (.docx, .doc)
- Microsoft Excel (.xlsx, .xls)
- Microsoft PowerPoint (.pptx, .ppt)
- Apple Pages (.pages), Numbers (.numbers), Keynote (.key)
- Plain text + CSV + TSV (.txt, .csv, .tsv)
- Images: PNG, JPEG, GIF, WebP, HEIC, HEIF
- ZIP archives (.zip)
Video belongs on a Walk & Talk recording, not on a generic record attachment. Executables (.exe, .msi, .dmg) are deliberately rejected so the workspace doesn't become a host for installers.
Size limit
Up to 4.5 MB per file. That fits the 90th percentile of operator-uploaded docs (signed quotes, adjuster estimates, spreadsheets, contracts). Larger files need a presigned direct-to-storage upload path which we'll add when a customer asks for it. If you hit the limit, compress the PDF or ZIP the bundle first.
Storage + security
Files live in Cloudflare R2 (the same private object storage Walk & Talk uses for photos and audio). Workspace isolation is enforced at the storage-key level: `attachments/{workspaceId}/{attachmentId}/{filename}`. Two workspaces with identically-named files never collide.
Downloads go through `/api/attachments/[id]/download`, which auth-checks against your Clerk session and your org's workspaces, then redirects to a fresh 5-minute signed R2 URL. We never store public URLs on the attachment row, so a leaked URL can't be replayed indefinitely and a deleted attachment is immediately unreachable.
Deleting an attachment removes both the R2 object AND the DB row in one transaction. No way to undo, so the UI asks for confirmation first.
Tier + availability
| Plan | Files |
|---|---|
| Free | Read-only of any existing files (no upload) |
| Pro ($19/mo) | Read-only of any existing files (no upload) |
| Business ($39/mo) | Upload + read + delete |
| Team ($69/mo) | Same as Business |
Free + Pro users still see the Files tab; the upload control is replaced with an upgrade card. If you downgrade after uploading files, nothing is deleted: the read surface continues to work on the lower plan.
What's coming
Bigger uploads via signed direct PUT (so the 4.5 MB cap can grow without rewriting the route). Per-file activity entries on the contact timeline (so you see 'Kelly uploaded contract.pdf' next to email + score-change events). Optional 'Folder' or 'Project' grouping for verticals where a single customer juggles multiple concurrent jobs, only if usage data shows it's needed.