Retool S3 Uploader & File Storage
Retool File Uploads to S3-Style Storage Without the IAM Setup
Store and manage files from your Retool internal tools.
Retool S3 uploader & file storage
Retool does ship a built-in file store — Retool Storage — but it's capped at roughly 5 GB per organization and 40 MB per file, and the bytes stay locked inside Retool with no permanent global-CDN URL you can embed in an email, a public page, or another app. So the moment you outgrow those caps or need a real shareable link, the textbook workaround is a Retool S3 uploader: stand up an S3 bucket, write an IAM policy, generate access keys, configure CORS for the Retool domain, and build signed-URL generation in a backend, which is easily a half-day of plumbing for what should be a one-line upload. files.link sits between those two options — when you outgrow Retool Storage's 5 GB/40 MB caps or need a permanent global-CDN URL, it's a drop-in S3 alternative for Retool internal tools: one REST API resource, a single query to upload, and a permanent CDN URL returned in the response, with no AWS console anywhere in the loop.
Concretely: add a REST API resource in Retool with base URL https://api.files.link and your API key in the Authorization header (raw key, no Bearer prefix). From a JavaScript query, take the file from {{ fileInput1.value[0] }} and run the upload flow — POST /v1/files/{folderId} to get a presigned URL and id, PUT the bytes to that URL, then POST /v1/files/confirm-upload with the id.
The response gives you a permanent CDN URL; write it back to your database with a SQL query, or display it immediately in an Image, PDF, Video, or Download component. Because the URL is permanent and edge-served, dashboards with dozens of embedded files stay fast and don't depend on regenerating short-lived links on every render.
Here's the entire upload as a single Retool JS query — bind it to your File Input's upload button, and it returns a permanent CDN URL you can write to your database or drop straight into an Image, PDF, or Download component:
// Retool JS query: upload fileInput1's file to files.link, return its permanent CDN URL.
const API = 'https://api.files.link/v1';
const API_KEY = '<YOUR_API_KEY>'; // store this in a Retool config variable, don't hardcode it
const FOLDER_ID = '<YOUR_FOLDER_ID>';
const file = fileInput1.files[0]; // the raw File object from the File Input component
// 1. Ask files.link for a presigned PUT URL and a file id
const { urls } = await (
await fetch(`${API}/files/${FOLDER_ID}`, {
method: 'POST',
headers: { Authorization: API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ filesMetadata: [{ name: file.name, size: file.size, type: file.type }] }),
})
).json();
const { url, id, key } = urls[0];
// 2. PUT the bytes straight to storage (no auth header — the signature is in the URL)
await fetch(url, { method: 'PUT', headers: { 'Content-Type': file.type }, body: file });
// 3. Confirm the upload so the file goes live
await fetch(`${API}/files/confirm-upload`, {
method: 'POST',
headers: { Authorization: API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ ids: [id] }),
});
// Permanent CDN URL — write it to your DB or bind it to an Image / PDF / Download component
return `https://cdn.files.link/${key}`;This fits the internal-tools use cases Retool is built for: an ops team uploading vendor invoices, a support tool attaching screenshots to tickets, an admin panel managing product imagery, or a review queue where staff open user-submitted documents. For anything sensitive, upload private and mint a signed URL on demand instead of exposing a public path — useful when an internal tool surfaces customer documents that shouldn't be world-readable.
The contrast with native Retool + S3 is mostly setup and ongoing maintenance: no bucket policy to get wrong, no IAM key to rotate, no CORS error to debug at 5pm. Billing is prepaid credits with predictable per-GB pricing and no separate egress charge, so a tool that suddenly serves a lot of files doesn't generate a surprise bandwidth invoice. files.link is purely the storage backend — your Retool queries, resources, and app logic stay exactly as they are.
Benefits With No Complexity
Global CDN delivery
Edge-cached worldwide
Signed-URL security
What You Get
Unlimited files
Unlimited storage
Public + Private storage
CDN ready links
Prepaid credits
More coming soon
How files.link Works
1. Upload
2. Copy
3. Use Anywhere
Why Developers Choose files.link
A Better Way to Store & Deliver Files
| Native Retool + S3 | Retool Storage | Cloudflare R2 | files.link | |
|---|---|---|---|---|
| Drop-in REST resource (no SDK) | ||||
| Permanent CDN URLs returned | ||||
| Global CDN delivery | ||||
| No 5 GB org / 40 MB file cap | ||||
| No IAM / CORS / bucket policy | ||||
| Signed URLs for private files | ||||
| Pay-as-you-go (prepaid credits) |
Calculate Your Needs
Storage
Egress
CDN Bandwidth
Start Retool Storage
- Global CDN delivery
- Edge-cached worldwide
- Signed-URL security
- Unlimited files
- Unlimited storage
- Public + Private storage
- No subscription — prepaid credits keep spend predictable