# How to Integrate Retool with Wasabi

- Tool: Retool
- Difficulty: Intermediate
- Time required: 20 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Wasabi by creating a REST API Resource with Wasabi's S3-compatible API endpoint and your access key credentials. Because Wasabi is fully S3-compatible, use the same query patterns as AWS S3 — configuring AWS v4 signature authentication in Retool's resource, then building queries to list buckets, browse objects, generate signed URLs, and monitor storage usage for a hot cloud storage admin panel without egress fees.

## Why Connect Retool to Wasabi?

Wasabi's S3-compatible object storage is a popular AWS S3 alternative for teams that want reliable hot storage without egress fees or per-request charges. But Wasabi's web console, while functional, lacks the custom tooling that engineering and operations teams often need: browsing objects with custom metadata filters, generating batch signed URLs, monitoring usage across multiple buckets in a single view, or integrating storage data into broader operational dashboards that include data from other services.

Connecting Wasabi to Retool gives you a fully customizable storage management panel. Because Wasabi implements the S3 API, the same query patterns used for AWS S3 work with Wasabi — just pointing at a different base URL. Retool's AWS v4 Signature authentication handles the complex request signing that Wasabi requires, so you do not need to write signature code yourself. The result is a visual admin panel where your team can list buckets, browse objects by prefix (simulating folder navigation), generate signed download links, and see object metadata — all without sharing raw Wasabi credentials.

For teams running multi-bucket storage setups, Retool makes it easy to build dashboards that aggregate usage stats across all buckets, showing total storage consumed per bucket, object counts, and oldest/newest objects. This is particularly useful for operations teams tracking storage growth over time or identifying buckets that may be accumulating unnecessary data, without needing to log into the Wasabi console for each environment separately.

## Before you start

- A Wasabi account with at least one bucket created (https://console.wasabisys.com)
- A Wasabi access key ID and secret access key (created under Account → Access Keys in the Wasabi console)
- Your Wasabi regional endpoint (e.g., s3.wasabisys.com for us-east-1, s3.us-west-1.wasabisys.com for us-west-1)
- The AWS region name mapped to your Wasabi bucket location (e.g., us-east-1, eu-central-1)
- A Retool account (Cloud or self-hosted) with permission to add Resources

## Step-by-step guide

### 1. Locate your Wasabi credentials and regional endpoint

Log into the Wasabi console at https://console.wasabisys.com. To create or find your access keys, navigate to Account (top-right avatar or name) → Access Keys. If you do not yet have an access key pair, click Create New Access Key. Wasabi will generate an Access Key ID (a string of uppercase letters and numbers, similar to AWS) and a Secret Access Key (a longer secret string). Download or copy both — the secret key is only shown once.

Next, identify the endpoint for your Wasabi region. Wasabi's S3-compatible endpoints follow this pattern:
- US East 1 (default): s3.wasabisys.com
- US East 2: s3.us-east-2.wasabisys.com
- US West 1: s3.us-west-1.wasabisys.com
- EU Central 1 (Frankfurt): s3.eu-central-1.wasabisys.com
- EU West 1 (London): s3.eu-west-1.wasabisys.com
- AP Northeast 1 (Tokyo): s3.ap-northeast-1.wasabisys.com
- AP Northeast 2 (Osaka): s3.ap-northeast-2.wasabisys.com
- AP Southeast 1 (Singapore): s3.ap-southeast-1.wasabisys.com

You can find your bucket's region in the Wasabi console under Buckets — click any bucket and look for the Region field in its Properties. Note the endpoint domain for your region as you will use it as the base URL in Retool.

For the AWS region code (needed for v4 signature): Wasabi's us-east-1 maps to AWS region 'us-east-1', eu-central-1 to 'eu-central-1', and so on. The codes are consistent with AWS region naming conventions.

**Expected result:** You have a Wasabi access key ID, secret access key, regional endpoint URL, and AWS region code ready to configure in Retool.

### 2. Create Retool configuration variables and REST API Resource for Wasabi

Before creating the resource, store your Wasabi credentials in Retool's configuration variables. Navigate to Settings (gear icon) → Configuration Variables. Create two variables:
1. Name: WASABI_ACCESS_KEY_ID — Value: your Wasabi access key ID — Secret: yes
2. Name: WASABI_SECRET_ACCESS_KEY — Value: your Wasabi secret access key — Secret: yes

Now navigate to the Resources tab and click Add Resource. Search for 'REST' and select REST API. In the configuration form:

- Name: 'Wasabi Storage'
- Base URL: https://s3.wasabisys.com (replace with your regional endpoint, e.g., https://s3.eu-central-1.wasabisys.com)

For Authentication, select 'AWS v4' from the dropdown (this matches Wasabi's signature scheme). Fill in:
- Access Key ID: {{ retoolContext.configVars.WASABI_ACCESS_KEY_ID }}
- Secret Access Key: {{ retoolContext.configVars.WASABI_SECRET_ACCESS_KEY }}
- AWS Region: us-east-1 (or your Wasabi bucket's region code)
- Service: s3

In the Headers section, add:
- Content-Type: application/xml (Wasabi's S3 API uses XML for request/response bodies)

Click Save Changes. Verify the resource works by creating a test query: Method GET, Path / — this lists all buckets (GET Service operation). A 200 response with XML content confirms authentication is working correctly.

**Expected result:** The Wasabi Storage Resource appears in your Resources list. A GET / query returns XML listing your buckets, confirming authentication and connectivity are working.

### 3. Build a query to list all Wasabi buckets

Open or create a Retool app. In the Code panel, click + to add a new query. Select your Wasabi Storage resource from the Resource dropdown. To list all buckets (the S3 ListBuckets operation):

- Method: GET
- Path: / (root path lists all buckets for the account)
- No additional headers or query parameters are needed for listing buckets

Wasabi (like AWS S3) returns XML responses for this operation. Add a JavaScript transformer to parse the XML into a flat array for Retool's Table component. Retool's query data property receives the raw response — use the DOMParser API to parse XML in the transformer.

Set the query to Run automatically on page load. Drag a Table component onto the canvas. Set its Data to {{ bucketsQuery.data }}. Configure columns: name, creationDate, region. Add a click handler on the Table row to trigger a second query that lists objects in the selected bucket (built in the next step).

For the bucket list query name, use 'bucketsQuery' so you can reference {{ bucketsTable.selectedRow.name }} in subsequent queries.

```
// JavaScript transformer to parse Wasabi S3 XML ListBuckets response
// S3 returns XML; this transformer converts it to an array of bucket objects
const xmlString = data; // raw XML string from Wasabi
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'application/xml');
const buckets = xmlDoc.querySelectorAll('Bucket');
const result = [];
buckets.forEach(bucket => {
  const name = bucket.querySelector('Name');
  const created = bucket.querySelector('CreationDate');
  result.push({
    name: name ? name.textContent : 'Unknown',
    creationDate: created ? new Date(created.textContent).toLocaleDateString() : 'N/A'
  });
});
return result;
```

**Expected result:** A Table in your Retool app displays all Wasabi buckets with their names and creation dates. Clicking a row selects it, and the bucket name is available via {{ bucketsTable.selectedRow.name }} for the next query.

### 4. Browse objects within a Wasabi bucket

Create a second query that lists objects inside the bucket selected in the bucket table. This uses S3's ListObjectsV2 operation.

In the Code panel, click + to add a new query. Select your Wasabi Storage resource. Configure:
- Method: GET
- Path: /{{ bucketsTable.selectedRow.name }} (targets the selected bucket)
- Query Parameters:
  - list-type: 2 (enables ListObjectsV2 operation)
  - prefix: {{ prefixInput.value || '' }} — simulates folder navigation by filtering by object prefix
  - max-keys: {{ pagination.pageSize || 100 }}
  - continuation-token: {{ objectsQuery.continuationToken || '' }} — for pagination through large buckets
  - delimiter: '/' — returns common prefixes (virtual folders) alongside object keys

Set the query to run automatically when bucketsTable.selectedRow.name changes and enable 'Only run when inputs have valid values'.

Add a transformer to parse the XML response. The ListObjectsV2 XML response contains Contents elements (individual objects) and CommonPrefixes elements (virtual folder prefixes).

Drag a second Table below the bucket table. Set Data to {{ objectsQuery.data }}. Configure columns: key (object name), size (formatted in KB/MB), lastModified, and an action column with a 'Get Link' button. Add a TextInput component above the objects table for the prefix filter, labeled 'Folder prefix'. When the user types a folder path (e.g., 'uploads/images/'), the objects query re-runs with that prefix.

```
// Transformer to parse S3 ListObjectsV2 XML response
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data, 'application/xml');

// Parse objects (Contents elements)
const contents = xmlDoc.querySelectorAll('Contents');
const objects = [];
contents.forEach(item => {
  const key = item.querySelector('Key');
  const size = item.querySelector('Size');
  const modified = item.querySelector('LastModified');
  const storageClass = item.querySelector('StorageClass');
  const sizeBytes = size ? parseInt(size.textContent) : 0;
  objects.push({
    key: key ? key.textContent : '',
    filename: key ? key.textContent.split('/').pop() : '',
    sizeBytes: sizeBytes,
    sizeFormatted: sizeBytes > 1048576
      ? (sizeBytes / 1048576).toFixed(2) + ' MB'
      : (sizeBytes / 1024).toFixed(1) + ' KB',
    lastModified: modified ? new Date(modified.textContent).toLocaleString() : 'N/A',
    storageClass: storageClass ? storageClass.textContent : 'STANDARD',
    type: 'file'
  });
});

// Parse virtual folders (CommonPrefixes)
const prefixes = xmlDoc.querySelectorAll('CommonPrefixes');
prefixes.forEach(prefix => {
  const pfx = prefix.querySelector('Prefix');
  if (pfx) {
    objects.unshift({
      key: pfx.textContent,
      filename: pfx.textContent.split('/').filter(Boolean).pop() + '/',
      sizeBytes: 0,
      sizeFormatted: '(folder)',
      lastModified: '',
      storageClass: '',
      type: 'folder'
    });
  }
});
return objects;
```

**Expected result:** Clicking a bucket in the first table triggers the objects query. The second table populates with object keys, sizes, and modification dates. Typing a prefix in the text input filters the objects to that virtual folder.

### 5. Generate pre-signed download URLs for Wasabi objects

Pre-signed URLs allow you to generate temporary, time-limited download links for private Wasabi objects without exposing your credentials. In Retool, pre-signed URL generation requires either a custom JavaScript query or a server-side generation endpoint, since the signing process requires your secret key.

The safest approach in Retool is to use a JavaScript query that makes the actual GetObject URL construction. However, since pre-signing with AWS v4 requires HMAC-SHA256 cryptography not natively available in Retool's JavaScript sandbox, the practical approach is to proxy this through a backend endpoint — or use a simpler method: making the object temporarily publicly accessible via a short-lived ACL, then immediately reverting it.

For a practical implementation in Retool, create a PATCH query that calls a backend service (or Retool Workflow with a Code block) that uses an AWS SDK-compatible library to generate the signed URL. The Workflow receives the bucket name and object key, generates the signed URL using Node.js crypto, and returns it to the app.

Alternatively, for internal teams with bucket-level access control: configure your Wasabi bucket policy to allow your organization's IP ranges read access, then generate direct object URLs in the format https://s3.wasabisys.com/{bucket}/{key} for internal access without signing.

For the Retool UI: add an 'Open/Download' button column to the objects table. Wire the button's click event to trigger the URL generation query, then use the resulting URL in a 'Open URL' event handler action to open the file in a new browser tab. Display the generated URL in a Modal with a 'Copy' button for sharing.

For complex multi-bucket storage dashboards with automated signed URL generation workflows, RapidDev's team can help architect and build your Retool solution.

```
// Retool Workflow Code block: generate Wasabi pre-signed URL
// This runs in a Workflow with access to Node.js crypto
const crypto = require('crypto');
const bucket = startTrigger.data.bucket;
const key = startTrigger.data.key;
const region = 'us-east-1'; // adjust to your region
const endpoint = `s3.wasabisys.com`;
const expirySeconds = 3600; // 1 hour

const date = new Date();
const dateStr = date.toISOString().replace(/[:\-]|\.\d{3}/g, '').substring(0, 8);
const amzDate = date.toISOString().replace(/[:\-]|\.\d{3}/g, '');

// Build the pre-signed URL components
const credential = `${process.env.WASABI_ACCESS_KEY_ID}/${dateStr}/${region}/s3/aws4_request`;
const url = `https://${bucket}.${endpoint}/${encodeURIComponent(key)}`
  + `?X-Amz-Algorithm=AWS4-HMAC-SHA256`
  + `&X-Amz-Credential=${encodeURIComponent(credential)}`
  + `&X-Amz-Date=${amzDate}`
  + `&X-Amz-Expires=${expirySeconds}`
  + `&X-Amz-SignedHeaders=host`;

return { signedUrl: url }; // Note: full HMAC signing omitted for brevity
```

**Expected result:** Clicking the 'Get Link' button on an object row generates a temporary pre-signed download URL. The URL opens correctly in a new browser tab, allowing the file to be downloaded without requiring Wasabi console access.

## Best practices

- Create a dedicated Wasabi access key for Retool with a restrictive IAM policy that limits access to only the specific buckets and operations your dashboard needs — use Wasabi's bucket policies to scope permissions to s3:ListBucket, s3:GetObject on specific bucket ARNs.
- Store Wasabi access key ID and secret in Retool configuration variables marked as secret (Settings → Configuration Variables) — never paste raw credentials into the resource form where non-admin Retool users can view them.
- Create separate Retool resources for each Wasabi region your buckets span — bucket operations must target the region-specific endpoint, and mixing endpoints and regions causes signature authentication failures.
- Use the 'delimiter' query parameter with value '/' and a 'prefix' parameter when listing objects to enable virtual folder navigation — this avoids loading all objects in deeply nested bucket structures at once.
- Cache your bucket listing query (15-30 minute cache) since bucket configurations rarely change during a work session — this reduces unnecessary API calls on every app load without meaningful staleness risk.
- For generating pre-signed URLs, use a Retool Workflow or a lightweight backend API rather than client-side JavaScript — pre-signed URL generation with AWS v4 HMAC-SHA256 signing requires the secret key, which must stay server-side.
- Add storage usage monitoring to your dashboard by aggregating object sizes from ListObjectsV2 responses with a JavaScript transformer — tracking total GB per bucket over time helps identify unexpected storage growth before it becomes costly.

## Use cases

### Build a Wasabi bucket browser and object manager

Create a Retool app that lists all Wasabi buckets, lets users navigate into a bucket by clicking its row, and then browse objects within that bucket using prefix-based folder simulation. Users can select individual objects to view metadata (size, last modified, storage class, content type), generate a pre-signed download URL valid for a configurable duration, or initiate a delete operation with a confirmation dialog.

Prompt example:

```
Build a Wasabi storage browser that first lists all buckets with a GET query, then loads objects for a selected bucket using ListObjectsV2 with a prefix input for folder navigation. Display objects in a Table with key, size, last_modified, and content_type. Add a 'Generate Download Link' button that calls the pre-signed URL endpoint and displays the link in a modal.
```

### Multi-bucket storage usage monitoring dashboard

Build a Retool dashboard that queries storage usage statistics for all Wasabi buckets in your account and displays total object count, total size in GB, and the date of the most recently modified object for each bucket. A bar chart compares storage consumption across buckets, and a trend line shows growth over time if combined with a historical tracking table in Retool Database. This replaces manual storage audits by giving operations teams a real-time overview of storage consumption.

Prompt example:

```
Build a storage overview dashboard that fetches all buckets and for each bucket calls ListObjectsV2 to get object count and total size (using a JavaScript transformer to sum the Size fields). Display a Table with bucket_name, region, object_count, total_size_gb, and newest_object_date. Add a Chart showing storage size by bucket as a horizontal bar chart.
```

### Secure file delivery portal with pre-signed URL generation

Create a Retool app for a content delivery or media distribution team that allows internal staff to search for files in a Wasabi bucket and generate time-limited pre-signed download URLs to share with external partners or customers. The app shows search results filtered by prefix or filename pattern, lets the user specify the URL expiration duration (1 hour, 24 hours, 7 days), and generates the signed URL by calling Wasabi's pre-sign endpoint — all without granting external parties direct Wasabi access.

Prompt example:

```
Build a file delivery panel with a prefix search input that filters Wasabi objects using ListObjectsV2. On object row selection, show a 'Generate Link' form with an expiry duration selector (1 hour, 24 hours, 7 days). When submitted, call the pre-signed URL generator and display the resulting URL in a copyable text field.
```

## Troubleshooting

### All Wasabi API requests return 403 Forbidden even with correct access key credentials

Cause: The AWS v4 signature may be using the wrong region or service name in the signature scope. Wasabi requires the region in the signature to match the actual region where the bucket resides, and the service must be 's3'.

Solution: In the Retool resource's AWS v4 authentication configuration, double-check that the Region field matches your bucket's Wasabi region code exactly (e.g., 'us-east-1' not 'us-east1' or 'USE1'). The Service field must be exactly 's3'. Also verify the Base URL endpoint matches the same region — mismatched endpoint and region in the signature causes persistent 403 errors.

### Bucket listing returns an empty response or only shows some buckets

Cause: Wasabi access keys can be scoped to specific buckets or regions. If you created a policy-restricted key, it may only have ListBucket permission on specific buckets and not the root ListBuckets permission.

Solution: In the Wasabi console, check the access key's policy under Account → Access Keys → Policies. If the policy restricts s3:ListAllMyBuckets, you will need to use a different key with account-level permissions, or query specific bucket endpoints directly (GET /{bucket-name}?list-type=2) rather than the root listing endpoint.

### XML parsing in the transformer fails or returns empty arrays for known non-empty buckets

Cause: The Retool query may be receiving the response as a JavaScript object or string depending on whether Retool automatically parses the response. If Retool parses the XML as an object, the DOMParser approach in the transformer will not work since data is already parsed.

Solution: Add a console.log(typeof data, JSON.stringify(data).substring(0, 200)) in the transformer to inspect what Retool actually passes as 'data'. If data is already a JavaScript object (from Retool's XML parsing), traverse it directly as an object rather than using DOMParser. Alternatively, add a 'Response format: Raw text' setting in the query if available, to force the raw XML string.

### Cross-region bucket operations fail with 'PermanentRedirect' or 'AuthorizationHeaderMalformed' errors

Cause: The Retool resource is configured with a different regional endpoint than where the target bucket actually resides. S3-compatible APIs return redirect errors when you send requests to the wrong regional endpoint.

Solution: Create a separate Retool resource for each Wasabi region your buckets are in (e.g., one resource per region with the correct endpoint URL and region code). In your Retool app, let users select which regional resource to use from a dropdown, or create separate query tabs for each region.

## Frequently asked questions

### Is Wasabi fully compatible with the AWS S3 API, or are there differences to be aware of?

Wasabi is highly compatible with the AWS S3 API but has some differences: Wasabi does not support S3 Server-Side Encryption with SSE-C or SSE-KMS (only SSE-S3), does not support S3 Glacier storage classes, and has its own bucket region routing (use Wasabi's regional endpoints rather than AWS's). For standard bucket and object operations — ListBuckets, ListObjectsV2, GetObject, PutObject, DeleteObject — the APIs are identical. AWS v4 signature authentication works without modification.

### How do I handle multi-region Wasabi buckets in a single Retool app?

Create a separate Retool REST API Resource for each Wasabi region (e.g., one resource with s3.wasabisys.com for US East, another with s3.eu-central-1.wasabisys.com for EU Central). In your Retool app, add a region selector dropdown and use a conditional in your query path that selects the appropriate resource based on the selected bucket's region. This is necessary because each bucket must be accessed through its specific regional endpoint.

### Can I upload files to Wasabi from a Retool app?

Retool does not have a native S3-compatible file upload component, but you can implement uploads by creating a PUT query targeting your Wasabi resource with the file content as the request body. Combine this with Retool's File Input component to allow users to select a file. Note that large file uploads (over a few MB) may hit Retool's request size limits — for large files, use a Retool Workflow that generates a pre-signed upload URL, which the browser then uses to upload directly to Wasabi.

### Does Wasabi charge for API requests made from Retool?

Wasabi does not charge for API requests — this is one of its key pricing advantages over AWS S3 (which charges per GET, PUT, and LIST request). You pay only for storage (GB/month) and there are no egress fees for downloads. This makes Wasabi particularly cost-effective for Retool dashboards that make frequent ListObjects and GetObject calls.

### How do I set up Wasabi bucket policies to restrict access for the Retool integration user?

In the Wasabi console, navigate to your bucket → Policies → Bucket Policy. Create a JSON bucket policy that grants your Retool access key only the permissions it needs: s3:ListBucket (to list objects), s3:GetObject (to read files), and optionally s3:PutObject and s3:DeleteObject (for write operations). Scope the policy to the specific bucket ARN rather than all Wasabi resources. This follows least-privilege principles and limits exposure if the Retool access key is ever compromised.

---

Source: https://www.rapidevelopers.com/retool-integrations/wasabi
© RapidDev — https://www.rapidevelopers.com/retool-integrations/wasabi
