Skip to main content
RapidDev - Software Development Agency
retool-integrationsREST API Resource

How to Integrate Retool with Square (Inventory & Catalog)

Connect Retool to Square's Inventory and Catalog APIs using a REST API Resource with OAuth 2.0 or a personal access token. Once connected, you can build inventory management dashboards that display real-time stock levels, flag low-stock items, manage catalog entries, and trigger purchase order workflows — all from a single Retool interface that goes far beyond Square's native dashboard.

What you'll learn

  • How to generate a Square access token and configure a REST API Resource in Retool
  • How to query Square's Catalog API to list and filter inventory items
  • How to retrieve real-time inventory counts using Square's Inventory API
  • How to use JavaScript transformers to calculate stock health and flag low-stock SKUs
  • How to set up a Retool Workflow that sends low-stock alerts on a schedule
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate17 min read25 minutesOtherLast updated April 2026RapidDev Engineering Team
TL;DR

Connect Retool to Square's Inventory and Catalog APIs using a REST API Resource with OAuth 2.0 or a personal access token. Once connected, you can build inventory management dashboards that display real-time stock levels, flag low-stock items, manage catalog entries, and trigger purchase order workflows — all from a single Retool interface that goes far beyond Square's native dashboard.

Quick facts about this guide
FactValue
ToolSquare (Inventory & Catalog)
CategoryOther
MethodREST API Resource
DifficultyIntermediate
Time required25 minutes
Last updatedApril 2026

Build a Real-Time Inventory Command Center on Top of Square

Square's built-in dashboard provides a solid starting point for retail inventory management, but it quickly reaches its limits when operations teams need cross-location aggregation, custom reorder thresholds, bulk catalog updates, or automated purchase order triggers. Retool bridges this gap by exposing Square's full Developer API through a REST API Resource, giving you all the building blocks for a purpose-built inventory command center tailored to your exact operational workflow.

The integration works through Square's two primary inventory-related API surfaces: the Catalog API (which manages product definitions, variants, pricing, and images) and the Inventory API (which tracks real-time stock counts by location and SKU). In Retool, you configure a single REST API Resource with your Square access token, then build individual queries for each API endpoint. Results bind directly to Table, Chart, and Form components, and event handlers on buttons can trigger restocking requests or catalog updates without leaving the Retool interface.

For multi-location retail operations, this approach is particularly powerful. A single Retool app can query inventory counts across all locations simultaneously, join catalog data with inventory data via JavaScript transformers, and surface a unified view showing which items are overstocked at one location and understocked at another. Retool Workflows can then run on a daily schedule to check count thresholds and send automated low-stock notifications via Slack or email.

Integration method

REST API Resource

Square connects to Retool via a REST API Resource targeting Square's Developer API (connect.squareup.com). You authenticate with a Square access token (personal access token for single-location or OAuth 2.0 for multi-merchant apps) configured once in the Resources tab. All queries — for inventory counts, catalog items, purchase orders, and location data — are then built visually in Retool's query editor without any code running on the client. Retool proxies every request server-side, keeping your Square credentials off the browser entirely.

Prerequisites

  • A Square Developer account with an application created at developer.squareup.com
  • A Square access token (Sandbox or Production) from your Square Developer Dashboard
  • A Retool account (Cloud or self-hosted) with permission to create Resources
  • At least one Square location ID (found in your Square Dashboard under Account & Settings → Locations)
  • Basic familiarity with REST APIs and HTTP methods (GET, POST, PUT)

Step-by-step guide

1

Generate a Square access token

Before configuring Retool, you need a Square access token. Navigate to developer.squareup.com and sign in with your Square account. Click 'Applications' in the left sidebar and select an existing application or click 'Create Your First Application' to make a new one. Give it a name like 'Retool Inventory Manager'. Once the application is created, click into it and navigate to the 'Credentials' tab. You will see two sets of credentials: Sandbox (for testing) and Production (for live data). For initial setup, copy the Sandbox access token — it starts with 'EAAAl' and is safe for development. When you are ready to connect to real inventory data, switch to the Production access token. Keep in mind that Square access tokens are scoped to specific applications and automatically include permissions based on your app's approved scopes. For inventory management, your app needs INVENTORY_READ, INVENTORY_WRITE, ITEMS_READ, and ITEMS_WRITE permissions — these are available by default for new Square Developer applications. Store this token securely; you will paste it into Retool in the next step. Do not commit it to any code repository or share it in plain text.

Pro tip: Use the Sandbox access token during development to avoid affecting live inventory data. Square's Sandbox environment mirrors the production API but uses test catalog items and simulated inventory counts.

Expected result: A Square access token string (starting with 'EAAA' for production or sandbox) copied and ready to paste into Retool.

2

Create a REST API Resource in Retool

In Retool, navigate to the Resources tab from the left sidebar of your organization homepage, or access it directly at your Retool instance URL followed by /resources. Click '+ Create new' and scroll through the connector list to select 'REST API'. On the resource configuration screen, fill in the Name field with something descriptive like 'Square API' so it is recognizable in the query editor across multiple apps. Set the Base URL to https://connect.squareup.com for production, or https://connect.squareupsandbox.com for Sandbox testing. Under Headers, click 'Add header' and add two headers: first, Content-Type with value application/json (required for all Square API requests that send a body), and second, Square-Version with value 2024-01-18 (or the latest API version from Square's changelog — pinning a version prevents breaking changes from affecting your integration). For authentication, select 'Bearer token' from the Authentication dropdown and paste your Square access token in the token field. Click 'Test connection' to verify — Retool will make a lightweight request to confirm the base URL and token are valid. If the test passes, click 'Save resource'. The resource is now available to all apps in your Retool organization. All requests through this resource are proxied server-side, so your Square token is never exposed in browser network traffic.

Pro tip: Add the Square-Version header to pin your integration to a specific API version. Without it, Square may automatically upgrade your requests to the latest version, which could introduce breaking changes.

Expected result: A saved REST API Resource named 'Square API' appears in your Resources list. The test connection confirms the base URL and Bearer token are valid.

3

Query the Catalog API to list inventory items

Open a new or existing Retool app and navigate to the Code panel at the bottom of the screen. Click '+ New query', select your Square API resource, and give the query a clear name like getCatalogItems. Set the Method to POST — Square's catalog search endpoint uses POST even for read operations, which is a common source of confusion. Set the URL path to /v2/catalog/search. In the Body section, select JSON and enter the search parameters. The request body controls which object types to return and supports cursor-based pagination. Square uses 'cursor' for pagination — the first response omits it when there are no more pages, and includes it when more results exist. Set the body to specify ITEM as the object type and enable include_related_objects to also get CatalogItemVariation records (which hold per-variant pricing and SKU data) in the same response. Set limit to 100 (the maximum per page). Click 'Run query' to test. Square returns a catalog_objects array where each object has type ITEM, a data field with item metadata, and a related_objects array containing the associated variants. Name your query getCatalogItems and note the structure of the response — you will flatten it in the next step using a JavaScript transformer.

catalog-search-body.json
1{
2 "object_types": ["ITEM"],
3 "include_related_objects": true,
4 "limit": 100,
5 "cursor": "{{ getCatalogItems.data.cursor || '' }}"
6}

Pro tip: Square's catalog search returns ITEM objects (product definitions) separate from ITEM_VARIATION objects (individual SKUs with prices). Use include_related_objects: true to get both in one request and avoid a second API call.

Expected result: The query returns a JSON response with a catalog_objects array containing your Square catalog items and their variants, plus a cursor field if there are more pages.

4

Retrieve inventory counts from Square's Inventory API

Create a second query to fetch real-time inventory counts. In the Code panel, click '+ New query', select your Square API resource, and name this query getInventoryCounts. Set the Method to POST and the URL path to /v2/inventory/counts/batch-retrieve. This endpoint accepts a list of catalog object IDs (the variant IDs from your catalog query) and location IDs, and returns current inventory counts for each combination. In the Body, provide location_ids as an array — you can hardcode your location IDs during development or reference a Select component if you want users to filter by location dynamically. Set the catalog_object_ids array to reference the variant IDs from your getCatalogItems query using Retool's double-brace syntax to extract them from the previous query's response. Set cursor to handle pagination using the same pattern as the catalog query. Run the query to verify it returns inventory count objects — each count has a catalog_object_id (the variant ID), location_id, quantity (as a string), and calculated_at timestamp. Note that Square returns quantity as a string, not a number, so your transformer will need to convert it with parseFloat(). This is a known Square API quirk that trips up many integrations.

inventory-counts-body.json
1{
2 "location_ids": ["YOUR_LOCATION_ID"],
3 "catalog_object_ids": {{ getCatalogItems.data.related_objects?.filter(o => o.type === 'ITEM_VARIATION').map(v => v.id) || [] }},
4 "cursor": "{{ getInventoryCounts.data.cursor || '' }}"
5}

Pro tip: Your Square Location ID is found in the Square Dashboard under Account & Settings → Locations. For multi-location setups, pass an array of all location IDs to get counts across all locations in a single request.

Expected result: The query returns an array of inventory count objects, each with catalog_object_id, location_id, quantity (as a string), and calculated_at. An empty counts array means either no inventory has been set or the variant IDs do not match.

5

Transform and join catalog and inventory data

Square's catalog and inventory data come from separate API endpoints and need to be joined on the variant ID to produce a unified view. Create a JavaScript transformer to merge these datasets. In the Code panel, click '+ New query', but this time select 'JavaScript' as the query type instead of a resource. Name it inventoryDashboardData. In the transformer, you will access the previous two queries' results directly using their names. First, extract the variant objects from the catalog response — they are in the related_objects array filtered to type ITEM_VARIATION. Build a lookup map from catalog item ID to item name by iterating over the catalog_objects array (type ITEM). Then, iterate over the inventory counts from getInventoryCounts and join each count to its variant data and parent item name using the ID maps. Convert quantity from string to number using parseFloat(). Add a derived field for stock status: 'Critical' when quantity is below 5, 'Low' when below your reorder threshold (reference a NumberInput component for a configurable threshold), and 'OK' otherwise. Return the merged array. Bind the output of this transformer to a Table component by dragging a Table onto the canvas and setting its Data source to {{ inventoryDashboardData.data }}. Add columns for item name, SKU, location, quantity, and stock status. Apply conditional row coloring by setting the Table's row color property to reference the stock_status field: red for Critical, yellow for Low, and no color for OK. For complex multi-location inventory operations with automated reorder workflows, RapidDev's team can help architect your full Retool solution.

transformer.js
1// Join catalog items with inventory counts
2const catalogItems = getCatalogItems.data.catalog_objects || [];
3const relatedObjects = getCatalogItems.data.related_objects || [];
4const inventoryCounts = getInventoryCounts.data.counts || [];
5const reorderThreshold = numberInput1.value || 10;
6
7// Build item name lookup: item_id -> item_name
8const itemNameMap = {};
9catalogItems.forEach(item => {
10 if (item.type === 'ITEM') {
11 itemNameMap[item.id] = item.item_data?.name || 'Unknown Item';
12 }
13});
14
15// Build variant lookup: variant_id -> { sku, item_id }
16const variantMap = {};
17relatedObjects.forEach(obj => {
18 if (obj.type === 'ITEM_VARIATION') {
19 variantMap[obj.id] = {
20 sku: obj.item_variation_data?.sku || 'N/A',
21 item_id: obj.item_variation_data?.item_id,
22 name: obj.item_variation_data?.name || 'Default'
23 };
24 }
25});
26
27// Merge inventory counts with catalog data
28return inventoryCounts.map(count => {
29 const variant = variantMap[count.catalog_object_id] || {};
30 const qty = parseFloat(count.quantity) || 0;
31 const status = qty < 5 ? 'Critical' : qty < reorderThreshold ? 'Low' : 'OK';
32 return {
33 item_name: itemNameMap[variant.item_id] || 'Unknown',
34 variant: variant.name,
35 sku: variant.sku,
36 location_id: count.location_id,
37 quantity: qty,
38 stock_status: status,
39 last_updated: new Date(count.calculated_at).toLocaleString()
40 };
41});

Pro tip: Square returns quantity as a string (e.g., '42') rather than a number. Always use parseFloat() when doing numeric comparisons — JavaScript's comparison operators will not work correctly on string quantities.

Expected result: The JavaScript transformer outputs a flat array of objects with item_name, sku, quantity, stock_status, and location_id fields. The Table component displays all inventory items with color-coded stock status rows.

6

Add a Workflow for automated low-stock alerts

With the dashboard built, create a Retool Workflow to send automated low-stock alerts on a schedule so ops managers are notified before stock runs out, not after. Navigate to the Workflows section in Retool (left sidebar → Workflows) and click '+ New Workflow'. Name it 'Square Low Stock Alert'. On the Workflow canvas, you will see a default Start block. Add a Schedule trigger by clicking the trigger icon and selecting 'Schedule' — configure it to run daily at 8:00 AM in your timezone using the cron expression. Add a Resource Query block by dragging it onto the canvas. Select your Square API resource, set it to POST /v2/inventory/counts/batch-retrieve with your location IDs, and name this block fetchInventory. Connect the Schedule trigger to this block. Add a Code block (JavaScript) connected after fetchInventory — this block filters the inventory counts to find items below threshold. Set your threshold directly in the code block using a constant (e.g., const REORDER_THRESHOLD = 10). The code should parse quantities, filter low-stock items, and format a summary message. Connect a final Resource Query block to send the alert — if you have Slack connected as a Resource in Retool, use a Slack resource query to post a message; alternatively use an HTTP POST to a Slack incoming webhook URL. Click 'Publish release' to activate the scheduled workflow. You can test it immediately using the 'Run now' button before the first scheduled execution. Every run is logged in the Workflow history with per-block status for easy debugging.

low-stock-filter.js
1// Code block: filter low-stock items and format alert message
2const counts = fetchInventory.data.counts || [];
3const REORDER_THRESHOLD = 10;
4
5const lowStockItems = counts
6 .filter(c => parseFloat(c.quantity) < REORDER_THRESHOLD)
7 .map(c => ({
8 variant_id: c.catalog_object_id,
9 location: c.location_id,
10 quantity: parseFloat(c.quantity),
11 alert: parseFloat(c.quantity) < 5 ? '🔴 CRITICAL' : '🟡 LOW'
12 }));
13
14if (lowStockItems.length === 0) {
15 return { message: 'All inventory levels are healthy.', count: 0 };
16}
17
18const lines = lowStockItems.map(i =>
19 `${i.alert} Variant ${i.variant_id} at location ${i.location}: ${i.quantity} units`
20).join('\n');
21
22return {
23 message: `Square Inventory Alert — ${lowStockItems.length} items need restocking:\n${lines}`,
24 count: lowStockItems.length
25};

Pro tip: Click 'Publish release' after configuring the Workflow — changes are auto-saved but only take effect for the Schedule trigger after publishing. The 'Run now' button lets you test immediately without waiting for the next scheduled time.

Expected result: The Workflow runs on schedule, fetches inventory counts from Square, filters low-stock items, and sends an alert message to your configured destination. The Workflow history shows each run with per-block execution status and output.

Common use cases

Build a multi-location inventory dashboard

Your retail chain has five locations all managing inventory in Square. You need a single dashboard where ops managers can see current stock levels for every SKU across all locations, filter by category, and spot items that are below reorder threshold. Retool lets you query Square's Inventory API for all location IDs simultaneously and join the results with catalog data to show item name, category, current count, and reorder flag in a unified table.

Retool Prompt

Build an inventory dashboard that queries Square's Inventory API for all catalog item variants across all location IDs. Display results in a Table with columns for item name, SKU, location, current quantity, and a 'Low Stock' badge (red) when quantity is below a configurable threshold input. Add a dropdown to filter by location and a search input for item name.

Copy this prompt to try it in Retool

Create a catalog bulk editor

Your merchandising team needs to update pricing, descriptions, and availability for dozens of catalog items at once during seasonal resets. Square's native catalog editor requires clicking into each item individually. The Retool app presents all catalog items in an editable Table where managers can change prices and availability in bulk, then submit a single PATCH request for all modified rows using Square's batch catalog update endpoint.

Retool Prompt

Build a catalog editor that lists all active Square catalog items (name, price, availability status, category) in a Table with inline editing enabled. Add a 'Save Changes' button that submits only modified rows to Square's /v2/catalog/batch-upsert endpoint. Include a category filter dropdown and a search bar.

Copy this prompt to try it in Retool

Set up automated low-stock purchase order alerts

Your operations team wants to receive a daily Slack message listing any SKUs that have fallen below reorder point across all Square locations. Using a Retool Workflow with a Schedule trigger, you can query Square's Inventory API each morning, filter for items below threshold, format a summary, and send the alert to a Slack channel — replacing a manual daily check that previously took 30 minutes.

Retool Prompt

Build a Retool Workflow with a daily Schedule trigger that fetches inventory counts from Square's Inventory API, filters for items where quantity is below the reorder_point field, groups results by location, and sends a formatted Slack message listing all low-stock items with their current counts and reorder points.

Copy this prompt to try it in Retool

Troubleshooting

Query returns 401 Unauthorized

Cause: The Square access token is invalid, expired, or belongs to the wrong environment (Sandbox token used against Production URL or vice versa).

Solution: Verify in your Square Developer Dashboard that the token is still active and matches the environment of your Base URL. Sandbox tokens (connect.squareupsandbox.com) and Production tokens (connect.squareup.com) are not interchangeable. Regenerate the token if needed and update the Bearer token in your Retool Resource configuration: Resources tab → select Square API → edit token → Save.

Inventory counts query returns an empty array even though items exist

Cause: Square's Inventory API only returns counts for catalog object IDs that have had inventory explicitly set. Items that have never had inventory tracked via Square show no count records — they are not returned with a count of zero.

Solution: Verify that inventory tracking is enabled for your items in the Square Dashboard under Items → select item → Inventory. Use Square's Physical Count endpoint (/v2/inventory/physical-counts) to initialize inventory for items that have never been counted. Alternatively, use the Catalog API response to show all items and join with a left-join-style transformer that defaults to 0 for missing inventory records.

typescript
1// Left join: show all catalog items even if no inventory count exists
2const countsByVariantId = {};
3(getInventoryCounts.data.counts || []).forEach(c => {
4 countsByVariantId[c.catalog_object_id] = parseFloat(c.quantity) || 0;
5});
6
7return variants.map(v => ({
8 ...v,
9 quantity: countsByVariantId[v.id] ?? 0
10}));

Catalog search returns no results despite items existing in Square

Cause: The catalog search request body is malformed or missing required fields, or the access token lacks ITEMS_READ scope.

Solution: Verify the request body includes object_types as an array: ["ITEM"]. Check that the Content-Type: application/json header is configured in your Resource. Confirm your Square application has ITEMS_READ scope approved in the Square Developer Dashboard under your application's permissions. For Sandbox, ensure you have created test catalog items in the Sandbox Dashboard.

Quantity values appear as strings in the Table instead of numbers

Cause: Square's Inventory API returns the quantity field as a string (e.g., '42'), not a number. If you bind inventory count data directly to a Table without a transformer, the quantity column displays as text and sorting/comparison operations fail.

Solution: Always parse quantity through a JavaScript transformer using parseFloat(count.quantity) || 0 before binding data to components. This ensures numeric sorting, comparison operators for threshold checks, and Chart components all work correctly.

typescript
1const qty = parseFloat(count.quantity) || 0;

Best practices

  • Store your Square access token as a secret configuration variable in Retool (Settings → Configuration Variables, marked as secret) rather than pasting it directly into the REST API Resource — this allows rotating the token without editing each resource individually.
  • Pin the Square-Version header in your Resource configuration to a specific API version string (e.g., 2024-01-18). Without pinning, Square may auto-upgrade your requests to newer API versions that contain breaking changes.
  • Use Square's Sandbox environment (connect.squareupsandbox.com) for all development and testing. Create a separate Retool Resource for Sandbox and Production so developers can switch environments without touching production credentials.
  • Implement cursor-based pagination for catalog and inventory queries — Square limits responses to 100 objects per page. Large catalogs will silently return incomplete data if you do not handle the cursor field.
  • Convert quantity from string to number (parseFloat) in your transformers before any arithmetic, comparison, or chart binding. Forgetting this step is the most common cause of incorrect stock status calculations.
  • Use Retool's query caching for catalog data (Query editor → Advanced → Cache results, set to 300 seconds) since catalog items change infrequently. Cache inventory counts for a shorter duration (30-60 seconds) to keep stock level displays reasonably current.
  • For multi-location operations, query all location IDs in a single inventory batch-retrieve request rather than making one query per location — this minimizes API call volume and keeps dashboard load times fast.

Alternatives

Frequently asked questions

Does Retool have a native Square connector?

No. Retool does not have a dedicated native connector for Square as of 2026. You connect via a REST API Resource using Square's Developer API. This works well in practice — you configure the base URL and Bearer token once, and Retool proxies all inventory and catalog requests server-side with no CORS concerns.

Can I connect Retool to multiple Square locations?

Yes. Square's Inventory batch-retrieve endpoint accepts an array of location IDs, so a single query can return counts across all your locations simultaneously. You can then filter by location in Retool using a Select component bound to a list of your location IDs, or display all locations side by side in a grouped Table.

How do I handle Square's Sandbox versus Production environments in Retool?

Create two separate REST API Resources: one with the Sandbox base URL (connect.squareupsandbox.com) and a Sandbox access token, and one with the Production base URL (connect.squareup.com) and a Production token. During development, point your queries at the Sandbox resource. Before deploying your Retool app to production users, update query resource references to the Production resource. Using Retool's resource environments feature, you can also configure a single resource with different credentials per environment.

Can I update inventory counts directly from Retool?

Yes. Use Square's /v2/inventory/changes endpoint with a POST request from Retool to record physical counts or adjustments. The request body specifies the change type (PHYSICAL_COUNT or ADJUSTMENT), catalog object ID, location ID, quantity, and occurred_at timestamp. Wire this to a Form component in Retool where warehouse staff can submit count corrections, with a Success event handler that refreshes the inventory dashboard query.

How can I automate purchase orders when Square inventory falls below reorder point?

Use Retool Workflows with a Schedule trigger that runs on a daily or hourly basis. The workflow queries Square's inventory counts, runs a JavaScript code block to filter items below your reorder threshold, and then sends a formatted alert to Slack or email, or creates records in your purchasing system via another Resource Query block. All logic runs server-side with full access to any Resource configured in your Retool organization.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Retool integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.