Build a Retool Dashboard from Google Sheets
Connect SheetsAPI to Retool and build an internal admin dashboard over your Google Sheet data in under 30 minutes - no backend code required.
Retool is a popular platform for building internal tools. Its REST API query builder connects to any JSON API - which means SheetsAPI is a first-class data source. This guide walks you through connecting your Google Sheet to Retool and building a searchable admin table with an edit panel.
Prerequisites
- A Retool account (free tier works)
- A Google Sheet with a header row
- A SheetsAPI account and a
YOUR_USER_KEYkey from the dashboard
1. Create a REST API resource in Retool
- Open Retool → Resources → Create new → REST API.
- Name it
SheetsAPI. - Set Base URL to
https://sheetsapi.gkit.mreshank.com. - Under Headers, add:
- Key:
Authorization - Value:
Bearer sk_your_api_key_here
- Key:
- Click Save.
For public sheets (no API key needed), skip the header.
2. Add a List query
- In your Retool app, add a new query.
- Choose the
SheetsAPIresource. - Method: GET
- URL:
/api/spreadsheets/YOUR_USER_KEY/Products - URL parameters:
limit→{{ table1.pageSize }}offset→{{ table1.pageIndex * table1.pageSize }}search→{{ searchInput.value ? "name:" + searchInput.value : "" }}sort→{{ sortSelect.value || "name" }}
- Check Run on page load.
Replace Products with your actual sheet tab name.
3. Wire the query to a Table component
- Add a Table component to the canvas.
- Set Data source to
{{ listQuery.data.data }}. - Enable Server-side pagination:
- Total rows:
{{ listQuery.data.meta.total }}
- Total rows:
- The table auto-generates columns from the JSON keys.
4. Add search and sort controls
Add a Text Input component (id: searchInput) with placeholder Search products….
Set the list query to Run on input change from searchInput.
Add a Select component (id: sortSelect) with options:
name→ Name A→Z-name→ Name Z→A-price→ Price (high first)price→ Price (low first)
Set Default value to name.
5. Add a detail panel
When a user clicks a row, show a right-side panel with the selected row's data:
- Add a Container component on the right.
- Add Text components inside, bound to
{{ table1.selectedRow.data.name }},{{ table1.selectedRow.data.price }}, etc. - Hide the container when nothing is selected:
Hidden →
{{ !table1.selectedRow.data }}
6. Add a POST / update query
SheetsAPI's POST endpoint writes a new row. To support adding records:
- Add a Form component with fields matching your sheet columns.
- Add a POST query:
- Method: POST
- URL:
/api/spreadsheets/YOUR_USER_KEY/Products - Body type: JSON
- Body:
{{ form1.data }}
- Add a Button that triggers the POST query, then runs
listQuery.trigger()to refresh.
7. Tips for production use
Cache aggressively
Add cache as a query param:
/api/spreadsheets/YOUR_USER_KEY/Products?limit=200
Save the result to a Retool Temporary State variable with a 5-minute TTL so repeated filter/sort interactions don't re-fetch from the API.
Use Retool's query chaining
Chain listQuery → refreshQuery so the table auto-reloads after every write:
- Select the POST query.
- Under Event handlers → Success, add Trigger query → listQuery.
Environment variables
Store your API key in Retool Resources rather than hard-coding it in query params. This keeps the key out of shared app definitions and allows different keys per environment (staging vs. production).
What you built
| Component | Retool element |
|---|---|
| Data table | Table with server-side pagination |
| Search | Text Input → URL parameter |
| Sort | Select → URL parameter |
| Detail panel | Container shown on row click |
| Add row | Form + POST query + refresh |
The complete setup takes under 30 minutes and requires zero backend code - SheetsAPI handles authentication, pagination, search, and sorting.