# How to Integrate Retool with Square

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

## TL;DR

Connect Retool to Square using a REST API Resource with a personal access token or OAuth 2.0. Configure the Square API base URL and Authorization header, then build queries to view transactions, manage catalog items, and track customer data across multiple locations. The setup takes about 20 minutes and creates a powerful POS operations dashboard.

## Why Connect Retool to Square?

Square's native dashboard provides solid reporting for individual business owners, but retail chains, restaurant groups, and multi-location businesses often need more than Square's built-in reports can offer. Connecting Retool to Square's API enables internal operations teams to build dashboards that aggregate transaction data across all locations, compare performance metrics between stores, and combine Square data with other business systems — capabilities that require custom development or expensive third-party reporting tools without Retool.

Square's API covers the full commerce stack: Payments (transaction history, refunds, disputes), Orders (order details, line items, modifiers), Catalog (product listings, pricing, inventory), Customers (CRM data, purchase history, loyalty), Locations (multi-location management), and Employees (staff data and timesheets). In Retool, these endpoints are queried visually through the REST API Resource, and the responses are displayed in Tables, Charts, and Forms without writing HTTP client code.

Common Retool-Square integration use cases include multi-location revenue dashboards showing daily sales by store and employee, catalog management panels where operations teams can bulk-update prices or toggle item availability without using Square's POS interface, and customer analytics dashboards that combine Square purchase history with loyalty program data. Square's sandbox environment provides a full testing API so the integration can be thoroughly validated before touching live payment data.

## Before you start

- A Square account with at least one active location and payment processing history
- A Square Developer account (free to create at developer.squareup.com)
- A Square personal access token or OAuth 2.0 credentials for your Square application
- A Retool account (Cloud or self-hosted) with permission to add Resources
- Basic familiarity with the Retool query editor and REST API Resource configuration

## Step-by-step guide

### 1. Create a Square Developer App and obtain an access token

Navigate to the Square Developer Portal at developer.squareup.com and sign in with your Square account. Click the New Application button (or go to My Applications). Give your app a name like 'Retool Operations Dashboard'. Accept the developer terms and click Create Application. You will be taken to your application's credential page.

On the Credentials tab, you will see two environments: Sandbox (for testing) and Production. Start with Sandbox. Copy the Sandbox Access Token — this is a long string starting with 'EAAAl' or similar. This token provides full API access to Square's sandbox environment where all data is simulated. When you are ready for production use, you will switch to the Production access token.

Square's sandbox environment is highly feature-complete — you can create test catalog items, simulate transactions, and test all API endpoints without affecting real payment data. This makes it ideal for building and testing your Retool integration before going live.

In Retool, navigate to Settings → Configuration Variables. Create two new variables: SQUARE_ACCESS_TOKEN (paste your Sandbox token first, then update to Production when ready) and SQUARE_LOCATION_ID (available on the Locations tab in the Square Developer Portal — copy the ID for your primary or test location). Toggle both as Secret. Click Save.

**Expected result:** A Square Developer App exists with a Sandbox access token. The token and a location ID are stored as Secret Configuration Variables in Retool. You are ready to configure the REST API Resource.

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

Navigate to the Retool home page and open the Resources tab. Click Add Resource. In the resource type selector, search for 'REST API' and click it to open the configuration form.

In the Name field, enter 'Square API'. In the Base URL field, enter Square's API base URL: https://connect.squareup.com/v2 — this is the base for Square's Connect API v2, which covers all modern Square endpoints including Payments, Orders, Catalog, Customers, Locations, and Employees. Note: for the sandbox environment, the base URL is the same — the environment is determined by which access token you use, not the URL.

In the Headers section, click Add header. Set Key to Authorization and Value to Bearer {{ retoolContext.configVars.SQUARE_ACCESS_TOKEN }}. This automatically includes your access token as a Bearer token in every request. Add a second header: Key = Content-Type, Value = application/json. Add a third header: Key = Square-Version, Value = 2024-05-15 (or the latest Square API version from Square's documentation — specifying the version ensures your Retool queries work consistently even as Square releases new API versions).

Click Save Changes. The Square API resource is now available for use in Retool queries.

**Expected result:** A 'Square API' REST API Resource is saved in Retool with the base URL, Bearer token, and Square-Version headers configured. It is ready for use in the query editor.

### 3. Build queries to fetch payments and location data

Open or create a Retool app. In the Code panel, click + New to create your first query. Name it getLocations. Resource = Square API, method = GET, path = /locations. This retrieves all Square locations associated with your account. Set Trigger to run automatically on page load. Click Run to verify you receive location data with IDs and names.

Create a second query named getPayments. Resource = Square API, method = GET, path = /payments. Add URL parameters: location_id = {{ locationSelect.value }}, begin_time = {{ startDatePicker.value | ISO 8601 }}, end_time = {{ endDatePicker.value | ISO 8601 }}, limit = 200. Square's Payments API requires date ranges in RFC 3339 format. Set Trigger to run automatically when locationSelect or date picker values change.

Create a third query named getOrders. Resource = Square API, method = POST, path = /orders/search. Square's order search uses a POST request with a JSON body containing filter criteria. Set Body Type to JSON with filters for location IDs and date range, and include field_filters for order state (COMPLETED, CANCELED). Set this query to Manual trigger.

Create a fourth query named getCatalogItems. Resource = Square API, method = GET, path = /catalog/list. Add URL parameter: types = ITEM,CATEGORY. This returns all catalog items and categories across all connected locations.

```
// JavaScript transformer to format payment data for Table display
// Attach to getPayments query (Advanced → Transform data)
const response = data;
if (!response || !response.payments) return [];

return response.payments.map(payment => {
  const amountMoney = payment.amount_money || {};
  const amount = amountMoney.amount ? (amountMoney.amount / 100).toFixed(2) : '0.00';
  const currency = amountMoney.currency || 'USD';

  return {
    id: payment.id,
    status: payment.status || 'UNKNOWN',
    amount: `${currency} $${amount}`,
    amountRaw: amountMoney.amount || 0,
    source: payment.source_type || 'UNKNOWN',
    locationId: payment.location_id,
    createdAt: payment.created_at
      ? new Date(payment.created_at).toLocaleString()
      : 'N/A',
    receiptUrl: payment.receipt_url || '',
    refunded: payment.refunded_money ? true : false
  };
});
```

**Expected result:** Four queries are configured: getLocations returns all Square locations, getPayments returns recent transactions for the selected location and date range, getOrders is ready for order searches, and getCatalogItems returns the product catalog.

### 4. Build the multi-location POS dashboard interface

Assemble the dashboard UI. At the top of the canvas, drag a Select component labeled 'Location'. Set Data source to {{ getLocations.data.locations }}, Label to {{ self.name }}, Value to {{ self.id }}. Add two Date Picker components: Start Date (default to 7 days ago) and End Date (default to today). Add a Button labeled 'Load Data' with event handlers triggering getPayments and getOrders.

Below the filters, drag four Stat components. Use a JavaScript transformer on getPayments.data to calculate: Total Revenue (sum of all payment amounts divided by 100), Transaction Count (count of payments), Average Transaction Value (total / count), and Refund Count (count of refunded payments). These display at the top for immediate KPI visibility.

Drag a Table component below the stats. Set Data source to {{ getPayments.data }} with the formatPayments transformer applied. Configure columns: createdAt, amount, source (card type), status (with green/red badge renderer), and a Refunded indicator. Enable row selection and add a 'View Receipt' link column using the receiptUrl field.

Drag a Chart component to the right of the Stat cards. Set type to Bar. Create a standalone transformer that groups payments by day and sums the amounts to create a daily revenue time series. Set X-axis to date and Y-axis to totalRevenue. This visualizes the sales trend over the selected period. For retail chains managing 10+ locations requiring advanced analytics and inventory reconciliation, RapidDev's team can help architect comprehensive Square + Retool solutions.

```
// Standalone transformer: daily revenue for Chart
// Groups payments by date and calculates daily total
const payments = getPayments.data;
if (!payments || !payments.payments) return [];

const dailyRevenue = payments.payments.reduce((acc, payment) => {
  if (payment.status !== 'COMPLETED') return acc;
  const date = new Date(payment.created_at).toLocaleDateString('en-US');
  const amount = (payment.amount_money?.amount || 0) / 100;
  acc[date] = (acc[date] || 0) + amount;
  return acc;
}, {});

return Object.entries(dailyRevenue)
  .map(([date, totalRevenue]) => ({
    date,
    totalRevenue: parseFloat(totalRevenue.toFixed(2))
  }))
  .sort((a, b) => new Date(a.date) - new Date(b.date));
```

**Expected result:** The dashboard shows a location selector and date range at the top, KPI stat cards (revenue, transactions, average value, refunds), a detailed payments Table with receipt links, and a daily revenue Bar chart.

### 5. Add catalog management and customer lookup functionality

Extend the dashboard with catalog management. Create a new Tab or Container on the canvas labeled 'Catalog Management'. In this section, drag a Table component and set Data source to {{ getCatalogItems.data.objects }}. Configure columns: item name, category, price (format from smallest unit), available locations (as comma-separated list), and status (ACTIVE/INACTIVE). Add column sorting and a keyword filter input.

Create a query named updateCatalogItem. Resource = Square API, method = PUT, path = /catalog/object. Set Body Type to JSON with a body that constructs a Square CatalogObject with the updated price or availability from form inputs. Set this to Manual trigger. Wire it to an Update button in the catalog Table with a confirmation dialog showing what will change.

For customer lookup, create a query named searchCustomers. Resource = Square API, method = POST, path = /customers/search. Body: { query: { filter: { email_address: { exact: '{{ customerEmailInput.value }}' } } } }. Set Trigger to run when the search form is submitted.

Create a follow-up query named getCustomerOrders. Resource = Square API, method = GET, path = /orders/{{ customersTable.selectedRow.id }}. Actually use the Orders search endpoint filtered by customer ID to get their purchase history. Display in a Table showing order date, items, total amount, and payment method. Add Stat components for total lifetime spend and visit count calculated by a transformer.

```
// POST body for Square Orders search filtered by customer
{
  "location_ids": ["{{ locationSelect.value }}"],
  "query": {
    "filter": {
      "customer_filter": {
        "customer_ids": ["{{ customersTable.selectedRow.id }}"]
      },
      "state_filter": {
        "states": ["COMPLETED"]
      },
      "date_time_filter": {
        "closed_at": {
          "start_at": "{{ new Date(Date.now() - 365 * 24 * 60 * 60 * 1000).toISOString() }}",
          "end_at": "{{ new Date().toISOString() }}"
        }
      }
    },
    "sort": {
      "sort_field": "CLOSED_AT",
      "sort_order": "DESC"
    }
  },
  "limit": 50
}
```

**Expected result:** The Catalog tab shows all Square items with filtering and an edit form. The Customer tab enables email-based customer lookup with full purchase history and lifetime value stats.

## Best practices

- Always start integration development using Square's Sandbox environment — it provides a full testing API with simulated transactions and catalog data without risking real payment operations.
- Store Square access tokens in Retool Configuration Variables marked as Secret — payment API credentials must never appear in browser network requests or app JavaScript.
- Always divide Square monetary values (amount_money.amount) by 100 before displaying — Square stores all amounts in the smallest currency unit (cents for USD, pence for GBP).
- Include the Square-Version header in your resource configuration to pin API behavior — Square regularly adds new API features and the version header ensures consistent behavior in your Retool queries.
- Add confirmation dialogs to all catalog update and refund operations — these actions directly affect live commerce operations and should require explicit user confirmation before executing.
- Use Square's idempotency_key field in POST and PUT requests (set to a unique value like Date.now() or a UUID) to prevent duplicate transactions if a Retool query is accidentally triggered twice.
- Build multi-location dashboards by querying each location separately and aggregating results in a JavaScript transformer rather than trying to query all locations in a single API call.

## Use cases

### Build a multi-location sales performance dashboard

Create a Retool dashboard that queries Square's Payments API for all transactions across every connected location, groups revenue by location and day, and displays a Chart comparing daily revenue trends across stores. Add Stat components showing total revenue today, average transaction value, and refund rate for the selected time period.

Prompt example:

```
Build a multi-location sales dashboard that shows daily revenue for each Square location in a bar chart, with stat cards for total revenue today, total transactions, and average order value. Include a date range picker to filter the data and a table showing each location's individual performance.
```

### Manage Square catalog items and update pricing across locations

Build a Retool admin panel that lists all Square catalog items with their current prices, available locations, and inventory counts. Add filtering by category and location, and include a form that lets operations staff update item prices, toggle availability, or apply a percentage discount to a selected category — all via Square API PATCH requests.

Prompt example:

```
Build a catalog management panel that lists all Square menu/product items with price, category, and which locations sell them. Include a bulk price update form where the user selects a category and enters a new price or percentage change, then updates all matching items via the Square API.
```

### Build a customer purchase history and loyalty panel

Create a Retool customer management dashboard that searches Square's Customer API by name or email, displays purchase history from the Orders API, calculates total lifetime value and average order frequency, and shows recent transactions in a Table — enabling staff to quickly look up a customer and understand their relationship with the business.

Prompt example:

```
Build a customer lookup panel with a search input that finds Square customers by name or email, shows their total lifetime spend and visit count in stat cards, and displays their last 10 transactions in a table with date, items purchased, and total amount.
```

## Troubleshooting

### API queries return 401 Unauthorized even though the access token appears correct

Cause: The access token is for the wrong environment (Sandbox token used against production or vice versa), or the token has been revoked due to application settings changes in the Square Developer Portal.

Solution: Verify which environment your access token belongs to by checking the Square Developer Portal credentials page for your app. The Sandbox and Production tokens are different values. If using Sandbox, ensure you are testing with Sandbox-generated data (Sandbox transactions, Sandbox catalog items). If the token was revoked or expired, regenerate it in the Square Developer Portal and update the SQUARE_ACCESS_TOKEN Configuration Variable in Retool.

### getPayments query returns an empty payments array even though transactions exist in Square

Cause: The date range parameters are not in the correct RFC 3339 format that Square requires, or the location_id does not match any location in the account.

Solution: Square requires dates in RFC 3339 format: '2026-04-01T00:00:00Z'. Ensure your date picker values are formatted correctly using new Date(startDatePicker.value).toISOString() in the URL parameter value field. Verify the location_id by running getLocations first and confirming the ID being passed matches an active location. Also check that the date range does not exceed Square's maximum query window for the Payments API.

```
// RFC 3339 date formatting for Square API parameters
// Use these as URL parameter values:
// begin_time: {{ new Date(startDatePicker.value).toISOString() }}
// end_time: {{ new Date(endDatePicker.value).toISOString() }}
```

### Catalog update query returns 409 Conflict when trying to update an item price

Cause: Square uses optimistic concurrency control on catalog objects — the version field in your update request does not match the current version stored in Square, indicating another update occurred since you fetched the item.

Solution: Before sending a catalog update, always re-fetch the current catalog item to get the latest version number. Include the version field in your PUT body: it must match Square's current version. Add a 'Refresh' step before the update that runs getCatalogItems again, then extract the version from the freshly fetched item and include it in the update body.

```
// Include version in catalog update body
{
  "idempotency_key": "{{ Date.now() }}",
  "object": {
    "type": "ITEM",
    "id": "{{ catalogTable.selectedRow.id }}",
    "version": {{ catalogTable.selectedRow.version }},
    "item_data": {
      "name": "{{ itemNameInput.value }}"
    }
  }
}
```

## Frequently asked questions

### Does Retool have a native Square connector?

No. Retool does not include a dedicated Square connector. Integration is achieved by configuring Square's Connect API as a REST API Resource in Retool's Resources tab with a Bearer token. Once configured with the base URL, access token header, and Square-Version header, all payment, catalog, and customer queries are built visually in Retool's query editor.

### Can Retool process refunds through the Square API?

Yes. Square's Refunds API (POST /refunds) allows creating refunds for completed payments. In Retool, configure a POST query targeting this endpoint with the payment_id and refund amount in the JSON body. Always add a confirmation dialog before executing refund queries, and test thoroughly in Square's Sandbox environment. Ensure your access token has the necessary permissions for refund operations.

### How do I handle Square's API pagination for large transaction histories?

Square's Payments API returns a cursor field in the response when there are more results beyond the current page. To fetch all pages, create a JavaScript query that loops: call the API, check for cursor in the response, and if present, add cursor as a URL parameter in the next request, repeating until cursor is absent. Alternatively, limit the date range in your queries to a few days at a time to keep response sizes manageable for real-time dashboard use.

### Can I use Retool to manage Square for multiple merchant accounts (for agencies or franchises)?

Yes, but multi-merchant management requires Square's OAuth 2.0 flow where each merchant authorizes your application, resulting in a separate access token per merchant account. Store each merchant's access token in a database and build a merchant selector in Retool that dynamically references the appropriate token (via a JavaScript query fetching it from the database and using it in the API call). Square's Connect API is designed for this multi-merchant pattern through their OAuth application model.

---

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