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 file upload and storage without setting up S3: add one REST resource, run one query, and get a permanent CDN URL back. 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. cdn22.net 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, with no AWS console anywhere in the loop.

The architecture is four hops and no infrastructure: Retool File Input → POST /v1/files/{folderId} on cdn22.net, which returns a presigned PUT URL and a file id → PUT the bytes straight to storage → POST /v1/files/confirm-upload → a permanent CDN URL you write to your database or bind to an Image, PDF, Video, or Download component. Set it up by adding a REST API resource in Retool with base URL https://api.cdn22.net/v1 and your API key in the Authorization header (the raw key, no Bearer prefix).

Because the returned 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 Retool file upload as a single JS query — bind it to your File Input's upload button and it returns the permanent CDN URL:

js
// Retool JS query: upload the file selected in fileInput1 to cdn22.net and
// return its permanent CDN URL.
const API = 'https://api.cdn22.net/v1';
const API_KEY = '<YOUR_API_KEY>'; // store this in a Retool config variable, don't hardcode it
const FOLDER_ID = '<YOUR_FOLDER_ID>';

// Retool's File Input exposes parallel arrays: .files (metadata) and
// .value (base64-encoded contents). Take the first selected file.
const meta = fileInput1.files[0];   // { name, size, type }
const base64 = fileInput1.value[0]; // base64 string of the file contents

// 1. Ask cdn22.net 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: meta.name, size: meta.size, type: meta.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': meta.type || 'application/octet-stream' },
  body: Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)),
});

// 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.cdn22.net/${key}`;

Prefer not to write JavaScript? The same three hops work as three plain REST queries wired together with {{ }} bindings and a success event handler:

text
Resource: REST API   Base URL: https://api.cdn22.net/v1
Headers:  Authorization: <YOUR_API_KEY>   (raw key, no "Bearer " prefix)

Query 1  createUpload   POST /files/<YOUR_FOLDER_ID>
  body: { "filesMetadata": [{ "name": "{{ fileInput1.files[0].name }}",
                              "size": {{ fileInput1.files[0].size }},
                              "type": "{{ fileInput1.files[0].type }}" }] }

Query 2  putBytes       PUT {{ createUpload.data.urls[0].url }}
  no Authorization header — the presigned signature is already in the URL

Query 3  confirmUpload  POST /files/confirm-upload
  body: { "ids": ["{{ createUpload.data.urls[0].id }}"] }
  on success → SQL query writes the permanent URL to your row:
  https://cdn.cdn22.net/{{ createUpload.data.urls[0].key }}

Keeping the API key private matters more in Retool than in a normal backend, because a JS query runs in the browser. The safest shape is a thin server-side proxy — a Retool Workflow step or an endpoint on your own backend — that holds the key and hands the Retool app nothing but a presigned URL:

js
// Optional proxy: the cdn22.net API key never reaches the Retool client.
// Deploy as a Retool Workflow step or on your own backend; the Retool query
// calls THIS endpoint instead of api.cdn22.net.
export default async function handler(req, res) {
  const { name, size, type } = req.body; // sent by the Retool query
  const r = await fetch(`https://api.cdn22.net/v1/files/${process.env.CDN22_FOLDER_ID}`, {
    method: 'POST',
    headers: { Authorization: process.env.CDN22_API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ filesMetadata: [{ name, size, type }] }),
  });
  const { urls } = await r.json();
  // Return only the short-lived presigned URL and the id — never the key.
  res.json({ url: urls[0].url, id: urls[0].id, key: urls[0].key });
}

Once the URL is saved, displaying it is a binding: point an Image component's src, a PDF viewer's URL, or a Download button's file URL at the stored column, and a Table cell can render it as a link. 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 (GET /v1/files/signed/{id}, 10-minute default) 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 no subscription — you pay only for the storage and bandwidth you actually use, and there's no separate egress charge, so a tool that suddenly serves a lot of files doesn't generate a surprise bandwidth invoice. cdn22.net is purely the storage backend; your Retool queries, resources, and app logic stay exactly as they are.

For the long-form walkthrough with download, preview, and table-cell patterns, read the Retool file upload guide; the upload a file guide covers the identical three calls from curl, a browser, or Node.js, and the cloud file storage API, file storage with CDN, file to link, and Next.js file storage pages cover the wider surface. Create an API key and point your first Retool query at it.

Retool upload architecture

Retool File Input → cdn22.net API → CDN URL

Five steps take a file a user drops into your internal tool and turn it into a permanent CDN URL stored on the record. No bucket, IAM policy, or CORS rule anywhere in the path — the Retool file upload guide walks the same flow in full, and the upload a file guide shows the identical three calls outside Retool.

  1. Add the REST API resource

    Base URL https://api.cdn22.net/v1, with the Authorization header set to your raw API key — no Bearer prefix. That single resource replaces the bucket, IAM user, access keys, and CORS rule a Retool S3 uploader would need. See API-key auth for key handling and rotation.

  2. Collect the file in Retool

    Drop in a File Input or File Button component. It exposes parallel arrays: fileInput1.files[0] holds { name, size, type } and fileInput1.value[0] holds the base64-encoded contents you decode before the PUT.

  3. Request a presigned upload

    POST /v1/files/{folderId} with the file metadata returns { url, id, key }. Because the PUT is presigned, the bytes go straight from the browser to storage instead of streaming through your Retool query or a backend you maintain.

  4. PUT the bytes, then confirm

    PUT the file to the presigned URL with no Authorization header — sending your API key there is the most common way this flow breaks — then POST /v1/files/confirm-upload with { ids: [id] } so the file goes live.

  5. Store and display the URL

    Write https://cdn.cdn22.net/{key} to your database with a SQL query, then bind it to an Image, PDF, Video, or Download component. Private files skip the public URL entirely: mint GET /v1/files/signed/{id} on demand instead. Delivery details live on the file storage with CDN page.

Security and cost notes

  • Keep the API key server-side where you can — a Retool Workflow step or your own endpoint returns only the presigned URL.
  • Never hardcode a key in a JS query; use a Retool config variable and rotate it from your dashboard.
  • Files that shouldn't be world-readable upload as private, then get a short-lived signed URL (10-minute default).
  • The presigned PUT carries no Authorization header — the signature in the URL is the authorization.
  • No subscription and no per-seat plan — prepaid credits keep spend predictable.
  • Pay only for the storage and bandwidth you use; there's no separate egress bill when a dashboard serves a lot of files.

Benefits With No Complexity

Global CDN delivery

Your files are served from 450+ edge locations worldwide.

Edge-cached worldwide

Files are cached close to your users for fast delivery.

Signed-URL security

Private files stay protected with time-limited access.

What You Get

Unlimited files

Upload as many files as you need.

Unlimited storage

There is no storage limit.

Public + Private storage

Private files are fully secured.

CDN ready links

Upload directly to 450+ edge locations worldwide.

Prepaid credits

No subscription. Pay only for the storage and bandwidth you use.

More coming soon

We have plenty of features coming!

How cdn22.net Works

1. Upload

Create a project and upload your first file.

2. Copy

Copy the CDN link.

3. Use Anywhere

Paste and enjoy the blazing speed.

Why Developers Choose cdn22.net

A Better Way to Store & Deliver Files

Retool StorageNative Retool + S3DIY bucket + CDNTemporary file linkscdn22.net
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
Files stay available after days pass
Pay-as-you-go (prepaid credits)

Calculate Your Needs

Storage

0GB

Egress

0GB

CDN Bandwidth

0GB
Total: $0.000/month

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
Start Retool Storage

Frequently Asked Questions

How do I upload from Retool to S3-style storage without configuring AWS?
Add a REST API resource pointed at https://api.cdn22.net with your API key in the Authorization header. In a JS query, take {{ fileInput1.value[0] }} and run POST /v1/files/{folderId} → PUT presigned URL → POST /v1/files/confirm-upload. The response's permanent CDN URL can be written to your DB or shown in a component — no bucket, IAM, or CORS needed.
What's the difference versus Retool's native S3 integration?
Retool's S3 resource only works after you create a bucket, write an IAM policy, generate keys, set CORS, and build signed-URL logic. cdn22.net skips all of that — it's one REST resource that returns the CDN URL ready to embed in Image, PDF, or Download components.
Does Retool have built-in file storage?
Yes — Retool Storage. It's a built-in store, but it's capped at roughly 5 GB per organization and 40 MB per file, and files stay locked inside Retool with no permanent global-CDN URL you can embed elsewhere. cdn22.net is the option for when you outgrow those caps or need an edge-served public or signed URL to use outside Retool.
How do I keep internal-tool files private?
Upload them private and mint a short-lived signed URL on demand from your query (GET /v1/files/signed/{id}, 10-minute default), rather than exposing a public path — useful when a tool surfaces customer documents that shouldn't be world-readable.
Can I upload from Retool without writing JavaScript?
Yes. Wire three REST queries together with {{ }} bindings: POST /files/{folderId} with the File Input's name, size, and type; a PUT to {{ createUpload.data.urls[0].url }} on a resource with no auth header; then POST /files/confirm-upload with the id. A success event handler runs the SQL query that saves https://cdn.cdn22.net/{key} to your row.
How do I keep my API key out of the Retool client?
A Retool JS query runs in the browser, so the safest shape is a thin proxy — a Retool Workflow step or an endpoint on your own backend — that holds the key and returns only the presigned upload URL and file id. The Retool app then calls your endpoint, and the key never leaves your server. If you do call the API directly, store the key in a Retool config variable rather than inline in a query.
How does a signed URL upload work from Retool?
You never sign anything yourself. POST /v1/files/{folderId} returns a presigned PUT URL whose signature is baked into the query string, so the browser PUTs the bytes straight to storage with no Authorization header and nothing large streams through your Retool query. Confirming with POST /v1/files/confirm-upload publishes the file.
How do I upload a Retool file to a CDN URL I can reuse?
The confirm step returns a permanent URL of the form https://cdn.cdn22.net/{key}, served from a global edge network. Save that string on your record and every downstream surface — a Retool Image or Download component, an email template, another internal tool — reads the same stable URL instead of a link that expires.
What does Retool file storage on cdn22.net cost?
Prepaid credits, no subscription and no per-seat plan: you pay only for the storage and bandwidth you actually use, with no separate egress charge. A quiet month costs less than a busy one, and nothing auto-renews.
General Questions
Is there a subscription?
No. cdn22.net uses prepaid credits, so storage, bandwidth, and API usage are deducted from your balance as you go. The app explains the payment step before uploads are enabled — no monthly subscription and no per-user fees.
What is cdn22.net?
cdn22.net is a developer-first file platform that makes it simple to store, secure, and deliver files globally. It provides signed URLs, public/private access, and an API-first design so you can integrate file delivery into any app without the usual complexity.
How does billing work?
cdn22.net uses prepaid credits. As you use storage, bandwidth, and API requests, credits are deducted daily. When your balance runs low, we automatically recharge it using your saved card. If an auto-recharge doesn't go through, your files and links stay put — you simply update your payment method or top up manually to keep going. No monthly subscriptions — just simple usage-based pricing.
How secure is my data?
All files are encrypted at rest and in transit. You can use signed URLs for private files, control access with permissions, and rely on enterprise-grade infrastructure for data protection.

Related

cdn22.net
Copyright © 2026
All rights reserved
ContactGuidesGlossaryStatusLegal