# How to Integrate Retool with Airtable

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

## TL;DR

Connect Retool to Airtable using a REST API Resource with a personal access token. Despite appearing in some lists as a native connector, Airtable requires the generic REST API approach. Once connected, you can build proper admin panels, bulk editors, and approval workflows that go far beyond Airtable's built-in views — with real SQL-style filtering, multi-step forms, and write-back capabilities.

## Replace Airtable's Limited Views with a Full Retool Admin Panel

Airtable is excellent for storing and organizing data collaboratively, but its built-in views — grid, gallery, kanban, calendar — are designed for data entry, not operational workflows. Teams quickly hit limitations when they need to cross-filter records across multiple bases, trigger external actions based on record status, or present data to stakeholders who should not have full Airtable edit access. Retool fills this gap by connecting directly to Airtable's REST API and turning your bases into full-featured admin panels.

The connection model is straightforward: Retool's REST API Resource stores your personal access token and proxies every request through its server-side backend. This means no CORS errors, no exposed tokens in browser network requests, and a single credential configuration that all queries in your app share. You build queries visually — specifying the HTTP method, path, and parameters — and bind results directly to Table, Chart, and Form components.

Note that Airtable deprecated its old API key authentication in February 2024. All new integrations must use personal access tokens (PATs) created in your Airtable account settings, scoped to the specific bases and operations your Retool app requires. This guide covers the current PAT-based approach throughout.

## Before you start

- An Airtable account with at least one base containing data you want to surface in Retool
- A Retool account (Cloud or self-hosted) with permission to create Resources
- An Airtable personal access token with data.records:read and data.records:write scopes
- The Airtable Base ID (found in the Airtable API documentation for your base, starting with 'app')
- The table name(s) you want to query from your Airtable base

## Step-by-step guide

### 1. Create an Airtable personal access token

Before configuring anything in Retool, you need a personal access token (PAT) from Airtable. Navigate to your Airtable account at airtable.com, click your avatar in the top-right corner, and select 'Developer hub'. In the left sidebar choose 'Personal access tokens', then click 'Create new token'. Give the token a descriptive name like 'Retool Integration'. Under Scopes, add at minimum: data.records:read (to list and retrieve records) and data.records:write (to create, update, and delete records). If you also need schema information — field names, types, and table structure — add schema.bases:read as well. Under Access, select 'Only these bases' and choose the specific bases your Retool app will use. This scopes the token to minimum required permissions. Click 'Create token' and copy the generated value immediately — Airtable will not show it again. Store it somewhere safe temporarily; you will paste it into Retool in the next step. Note: if you are building on behalf of a team, consider whether a service account PAT (created under a shared Airtable account) is more appropriate than your personal token, since PATs are tied to individual accounts.

**Expected result:** A personal access token string starting with 'pat' that is ready to paste into Retool.

### 2. Create a REST API Resource in Retool

In Retool, navigate to the Resources tab in the left sidebar (or go to your organization's Retool homepage and click Resources at the top). Click the '+ Create new' button or '+ Add resource', then scroll through the connector list and select 'REST API'. On the resource configuration screen, fill in the following fields: Name — give it a clear name like 'Airtable (Company Base)' so it is easy to identify in the query editor. Base URL — enter https://api.airtable.com. For Authentication, select 'Bearer token' from the dropdown. In the token field, paste the personal access token you created in the previous step. Leave all other fields at their defaults for now. Click 'Test connection' — Retool will make a lightweight request to verify the token is valid and the base URL is reachable. If the test passes, click 'Save resource'. The resource is now available to all apps in your Retool organization. If you need to connect to multiple Airtable accounts or want to separate read-only from read-write access, create separate REST API resources for each. All queries made through this resource are proxied server-side — the bearer token is never sent to the browser.

**Expected result:** A saved REST API Resource named 'Airtable' appears in your Resources list with a green connection indicator.

### 3. Write a query to list records from a table

Open the Retool app where you want to display Airtable data (or create a new app). In the Code panel at the bottom, click '+ New query' and select your Airtable REST API resource. Set the Method to GET. For the URL path, enter /v0/{baseId}/{tableName} — replacing {baseId} with your actual Airtable Base ID (found at airtable.com/developers/web/api/introduction when you select your base; it starts with 'app') and {tableName} with your table name URL-encoded if it contains spaces (e.g., 'Content%20Calendar'). Alternatively, you can reference Retool component values dynamically: /v0/appXXXXXXXXXXXXXX/{{ select1.value }}. Add URL parameters to control the response. Under Params, add filterByFormula with a value like NOT({Status} = 'Archived') to exclude certain records, sort[0][field] to sort by a specific field name, sort[0][direction] set to 'desc' or 'asc', maxRecords set to 100 to limit page size, and offset set to {{ getRecords.data.offset || '' }} for pagination. Click 'Run query' to test. Airtable returns a JSON object with a records array — each record has an id, createdTime, and fields object. Name this query something descriptive like getVendors.

```
{
  "method": "GET",
  "path": "/v0/appYOURBASEIDHERE/Vendors",
  "params": {
    "filterByFormula": "NOT({Status} = 'Archived')",
    "sort[0][field]": "Created",
    "sort[0][direction]": "desc",
    "maxRecords": "100",
    "offset": "{{ getVendors.data.offset || '' }}"
  }
}
```

**Expected result:** The query returns a JSON response with a records array. Each record contains an id field and a fields object with your table's column data.

### 4. Transform the response and bind to a Table component

Airtable's API returns records in a nested format — each record has id, createdTime, and fields as a nested object. Retool's Table component expects a flat array of objects. You need a JavaScript transformer to flatten this structure. In the query editor for your getVendors query, click the 'Advanced' tab, then toggle on 'Transform results'. This opens an inline transformer editor where you write a JavaScript function. The transformer receives the raw API response as the data variable and should return a flat array. Write the transformation to map each record to a flat object combining the record id with all field values. After writing the transformer, click Run to verify the output is a flat array. Now drag a Table component from the component panel onto your canvas. In the Table's properties on the right, set the Data source to {{ getVendors.data }}. The table should populate with your flattened records. Configure column visibility, rename headers as needed, and set column types — for example, change a status column to type Select to show a colored badge. If you want pagination, enable it in the Table's properties and set the query's offset parameter to {{ table1.paginationOffset }}.

```
// Transformer: flatten Airtable records into a flat array
const records = data.records || [];
return records.map(record => ({
  id: record.id,
  createdTime: new Date(record.createdTime).toLocaleDateString(),
  ...record.fields
}));
```

**Expected result:** The Table component displays a row for each Airtable record, with columns corresponding to your table's fields. The record id is included as a hidden or visible column for use in update queries.

### 5. Add a form to create and update records

To write data back to Airtable, you need additional queries using POST (create) and PATCH (update) methods. For updating an existing record: create a new query, select your Airtable resource, set Method to PATCH, and set the path to /v0/appYOURBASEIDHERE/Vendors/{{ table1.selectedRow.id }}. In the Body section, select JSON and enter a fields object with the fields to update — reference component values using Retool's double-brace syntax for each field. For creating a new record: create another query, set Method to POST, use path /v0/appYOURBASEIDHERE/Vendors, and in the body set a fields object with all required field values from your form components. Drag a Form component onto the canvas to serve as your input UI. Add TextInput, Select, and DatePicker components inside the form. Wire the form's Submit button to trigger your create query using an event handler: click the Submit button → Event Handlers → Add handler → Action: Trigger query → select your createVendor query. On the create query's Success event handler, add: Trigger query → getVendors to refresh the table, and Show notification with message 'Record created successfully'. Test by filling in the form and clicking Submit — the new record should appear in Airtable and your Retool table should refresh automatically.

```
{
  "method": "PATCH",
  "path": "/v0/appYOURBASEIDHERE/Vendors/{{ table1.selectedRow.id }}",
  "body": {
    "fields": {
      "Status": "{{ statusSelect.value }}",
      "Notes": "{{ notesInput.value }}",
      "Last Updated By": "{{ current_user.email }}"
    }
  }
}
```

**Expected result:** Submitting the form creates a new record in Airtable and immediately triggers the list query to refresh the Table component. Clicking a row and saving updates the record in-place.

### 6. Handle pagination and large bases

Airtable's API returns a maximum of 100 records per request. For bases with more than 100 records, the response includes an offset field that acts as a pagination cursor. To implement load-more or full pagination in Retool, you need to handle this offset value. The simplest approach for smaller bases (under a few hundred records) is to chain multiple queries: run the first page, check if data.offset exists, and if so, run a second query with that offset value. For larger bases, implement proper server-side pagination using Retool's Table pagination feature. Enable pagination on your Table component (set Pagination type to 'Server-side'), then in your query use {{ table1.paginationOffset }} as the offset parameter. Add a pageSize URL parameter set to {{ table1.pageSize }}. When users click Next in the table, Retool automatically updates paginationOffset and re-runs the query. For the Table component to know the total record count (needed for page navigation), fetch the total using Airtable's COUNTA formula query or maintain a count field in a summary table. For complex integrations involving multiple Airtable bases, cross-base transformations, and automated sync workflows, RapidDev's team can help architect and build your Retool solution.

```
// JavaScript query to fetch all records by following offsets
const allRecords = [];
let offset = '';

do {
  const params = {
    maxRecords: 100,
    ...(offset ? { offset } : {})
  };
  const response = await utils.executeQuery('getVendors', params);
  allRecords.push(...(response.records || []));
  offset = response.offset || '';
} while (offset);

return allRecords.map(record => ({ id: record.id, ...record.fields }));
```

**Expected result:** Large Airtable bases load correctly with pagination controls visible in the Table component. Users can navigate between pages without seeing incomplete data.

## Best practices

- Create a dedicated Airtable service account (separate Airtable user) for production Retool integrations rather than using a personal token tied to an individual employee — this prevents access loss when team members leave.
- Scope personal access tokens to the minimum required bases and permissions. A read-only dashboard should use a token with only data.records:read; never use a token with full write access where reads suffice.
- Store the Airtable PAT as a configuration variable in Retool (Settings → Configuration Variables) marked as 'secret', and reference it in the resource as {{ retoolContext.configVars.AIRTABLE_PAT }} rather than hardcoding the token value in the resource.
- Use Airtable's filterByFormula parameter in queries rather than fetching all records and filtering in a transformer — this reduces API payload size and keeps your app fast even as your base grows.
- Add query caching (Query editor → Advanced → Cache results) for read-heavy dashboards where data freshness of a minute or two is acceptable. This reduces Airtable API calls and improves perceived performance.
- Use GUI mode (or POST/PATCH queries with explicit field lists) for write operations rather than constructing field objects dynamically from user input — this prevents accidental overwrites of fields you did not intend to modify.
- Handle Airtable's 5 requests per second rate limit by adding event handler debounce settings on search inputs and filter selects, preventing a new query from firing on every keystroke.

## Use cases

### Build a vendor approval dashboard

Your team tracks vendor onboarding in an Airtable base with fields for company name, contact, status, and contract value. You need an internal tool where ops managers can review pending vendors, update their status to Approved or Rejected, and add internal notes — all without giving them full Airtable editor access. Retool lets you build this as a Table with inline status dropdowns, a side panel for notes, and a Save button that PATCHes the record back to Airtable.

Prompt example:

```
Build an admin panel that displays all records from the 'Vendors' table in an Airtable base, filtered to show only records where Status is 'Pending'. Include a dropdown to change Status to 'Approved' or 'Rejected' and a text area for internal notes. Add a Save button that updates the record via PATCH request.
```

### Create a cross-base inventory reconciliation tool

You maintain inventory data across two Airtable bases — one for warehouse stock and one for e-commerce orders. A Retool app can query both bases simultaneously, join the data in a JavaScript transformer, and surface discrepancies in a single table. Ops staff can then update stock levels directly from Retool without switching between two Airtable views.

Prompt example:

```
Build a reconciliation dashboard that queries two Airtable bases (Warehouse Stock and E-commerce Orders), joins them by SKU in a JavaScript transformer, and displays a table showing current stock, pending orders, and the calculated available quantity. Add a bulk update form to correct stock levels.
```

### Build a content publishing queue manager

Your marketing team tracks blog posts, social content, and campaign assets in Airtable with fields for title, author, publish date, status, and attachments. The Retool app serves as the editorial dashboard where editors can filter by author or date range, update publish statuses in bulk, and see a timeline chart of upcoming content — capabilities that go beyond Airtable's native calendar view.

Prompt example:

```
Build a content queue dashboard that displays all records from the 'Content Calendar' Airtable table. Add date range pickers to filter by scheduled publish date, a status filter dropdown, and a bulk status update button. Show a Bar Chart of content count by week using the Chart component.
```

## Troubleshooting

### Query returns 401 Unauthorized error

Cause: The personal access token is invalid, expired, or the token lacks the required scopes for the operation you are attempting.

Solution: Open the Airtable Developer Hub, find the token used in your Retool resource, and verify it has data.records:read scope. Check that the token has not been revoked. If you recently rotated the token, update the Bearer token value in your Retool Resource configuration (Resources tab → select your Airtable resource → edit the token field → Save).

### Query returns 404 Not Found for a valid table name

Cause: The Base ID or table name in the query path is incorrect. Table names are case-sensitive and must match exactly — including spaces and special characters. The Base ID must start with 'app' and is specific to each base, not the workspace.

Solution: In Airtable, open the specific base you are targeting and navigate to airtable.com/developers/web/api/introduction. Select your base from the dropdown. Copy the exact Base ID shown — it looks like appXXXXXXXXXXXXXX. For table names, copy the exact name from the Airtable interface including any capitalization and spaces, then URL-encode spaces as %20 in the query path.

### Transformer output is empty or missing fields

Cause: Airtable only returns fields that have values — fields with empty or null values are omitted from the API response entirely. The spread operator in the transformer correctly handles present fields, but components bound to missing fields show undefined.

Solution: Add default values in your transformer for fields that may be absent. Use nullish coalescing to supply fallbacks for each expected field.

```
return records.map(record => ({
  id: record.id,
  name: record.fields['Company Name'] ?? 'N/A',
  status: record.fields['Status'] ?? 'Unknown',
  notes: record.fields['Notes'] ?? '',
  value: record.fields['Contract Value'] ?? 0
}));
```

### PATCH request returns 422 Unprocessable Entity

Cause: The request body contains a field name that does not match exactly, or you are sending a value of the wrong type for a field (e.g., sending a string to a Number field, or an invalid option to a Single Select field).

Solution: Log the raw error response body — Airtable includes a descriptive error message indicating which field caused the problem. Verify field names match exactly (including case and spaces). For Select fields, the value must exactly match one of the defined options. For linked record fields, values must be an array of record IDs, not display values.

## Frequently asked questions

### Does Retool have a native Airtable connector?

No. Despite Airtable sometimes appearing in connector lists, Retool does not have a dedicated native connector for Airtable as of 2026. You must connect via a generic REST API Resource using Airtable's Web API. This works just as well in practice — Retool proxies the requests server-side and you get full access to all Airtable API endpoints.

### Can I connect multiple Airtable bases to the same Retool app?

Yes. You can create multiple REST API Resources (one per Airtable account or one shared resource for all bases), and then reference different base IDs and table names in each query's URL path. A single Retool app can query and join data from multiple Airtable bases simultaneously using JavaScript transformers.

### Is it safe to store my Airtable personal access token in Retool?

Yes, when stored correctly. Store the token as a secret configuration variable in Retool (Settings → Configuration Variables, marked as secret) rather than pasting it directly into the resource configuration. Secret config vars are never exposed to the browser or end users. Retool also proxies all API requests server-side, so the token is never visible in browser network requests.

### How do I handle Airtable's 100-record page limit?

Airtable returns an offset field in responses when there are more records to fetch. For tables under a few hundred records, you can chain queries using a JavaScript query that loops until offset is empty. For larger bases with thousands of records, use Retool Table's server-side pagination feature and pass the offset value as a query parameter, fetching only the current page on each navigation action.

### Can I use Retool to automate Airtable updates on a schedule?

Yes, using Retool Workflows. Create a Workflow with a Schedule trigger and a Resource Query block targeting your Airtable REST API resource. The workflow runs server-side on a cron schedule and can read from other data sources (like a database), transform the data, and write updated records to Airtable via PATCH or POST requests. This works without any user interaction.

---

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