# How to Integrate Retool with Ecwid

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

## TL;DR

Connect Retool to Ecwid using a REST API Resource with a Bearer token (Ecwid access token). Once configured, you can build store management panels that view and update products, process orders, and manage store settings — providing a faster admin interface than Ecwid's built-in dashboard for SMBs running embeddable storefronts.

## Build a Lightweight Store Admin Panel for Ecwid with Retool

Ecwid's strength is its embeddable widget model — store owners can add a fully functional e-commerce storefront to any website, CMS, or social media page without rebuilding their existing site. However, as stores grow in product count and order volume, Ecwid's native admin interface can feel limiting for operations teams that need bulk product updates, custom order views, or integrations with internal fulfillment systems. Retool provides a way to build a custom admin layer on top of Ecwid's REST API that matches your team's exact operational workflow.

The Ecwid REST API is structured around your store ID — all endpoints include your unique store identifier in the path, and each request is authenticated with a store-scoped access token. In Retool, you configure these as a REST API Resource once, then build query-driven UIs for the specific operations your team performs most: processing orders, updating stock levels, managing product categories, or pulling sales reports.

For SMBs using Ecwid embedded in WordPress, Wix, or a custom website, a Retool admin panel is particularly valuable when the built-in store admin does not integrate with other business tools already connected to Retool — for example, viewing Ecwid orders alongside a customer support database or a shipping provider API.

## Before you start

- An Ecwid store with at least some products or orders to surface in Retool
- A Retool account (Cloud or self-hosted) with permission to create Resources
- An Ecwid REST API access token and your store ID, obtained from your Ecwid Control Panel
- Your Ecwid store ID (a numeric ID visible in your Ecwid Control Panel URL and API settings)
- Basic familiarity with Retool's query editor and component panel

## Step-by-step guide

### 1. Generate an Ecwid REST API access token

Ecwid provides access tokens through their developer program and the native apps system. To get an access token for your store, log into your Ecwid Control Panel at my.ecwid.com. Navigate to Settings → API. On the API settings page, you will find the Store ID — a numeric value that appears prominently and is also visible in the URL of your Control Panel pages. Copy this store ID and save it. For generating an access token, Ecwid offers a few options depending on your use case. For a private integration (connecting your own store to Retool), use the 'Legacy API keys' option if available, or go through Ecwid's native app OAuth flow to generate a token with the scopes you need. Ecwid access tokens are scoped to specific permissions: 'read_catalog' for product access, 'update_catalog' for product modifications, 'read_orders' for order access, and 'update_orders' for order modifications. Choose only the scopes your Retool app requires. If your Ecwid account is on a Business or higher plan, you may also be able to generate a secret API key directly from the Control Panel under Settings → API → Legacy API key. Copy the generated access token securely — you will paste it into Retool as a Bearer token. Note that some Ecwid features (like certain webhook or advanced catalog APIs) may require a paid plan tier.

**Expected result:** You have your Ecwid Store ID (numeric) and an API access token with appropriate read/write scopes ready to configure in Retool.

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

In Retool, open your organization homepage and navigate to the Resources tab in the left sidebar. Click '+ Create new', scroll to 'REST API', and click to begin configuration. In the Name field, enter 'Ecwid Store API' or include your store name if you manage multiple stores. For the Base URL, enter https://app.ecwid.com/api/v3/{storeId} — replacing {storeId} with your actual numeric store ID (for example, https://app.ecwid.com/api/v3/12345678). Including the store ID in the base URL means all queries automatically target your specific store without needing to include it in every query path. For Authentication, select 'Bearer token' from the dropdown and paste your Ecwid access token into the token field. Add a default header: click 'Add header', enter key as Content-Type and value as application/json. This ensures POST and PUT requests are interpreted as JSON by Ecwid's API. Click 'Save resource'. Retool proxies all requests through its server-side backend, so your access token is never transmitted to browser clients. If you need to connect multiple Ecwid stores, create separate resources for each store — name them clearly to avoid confusion in the query editor.

**Expected result:** A saved REST API Resource named 'Ecwid Store API' appears in Retool's Resources list with the correct store-specific base URL and Bearer token authentication.

### 3. Write queries to fetch products and orders

Open your Retool app or create a new one. In the Code panel, click '+ New query' and select your Ecwid Store API resource. Create a product listing query: set Method to GET and URL path to /products. Add URL parameters to control the response — offset set to {{ productsTable.paginationOffset || 0 }} for pagination, limit set to 100, keyword set to {{ searchInput.value }} for search filtering, and enabled set to true to show only active products. Name this query getProducts. Create an orders query: Method GET, path /orders. Add params: offset set to {{ ordersTable.paginationOffset || 0 }}, limit set to 100, paymentStatus set to PAID, fulfillmentStatus set to {{ statusFilter.value || '' }}, and dateFrom and dateTo set from DatePicker components if you want date range filtering. Name this query getOrders. Run each query by clicking Run to verify the response structure. Ecwid returns responses with a total field for pagination, an offset field showing the current position, and an items array containing the actual data. For the products endpoint, the response object is { total, count, offset, limit, items: [...] }. For orders, the structure is similar. Note the exact field names from the raw response before writing transformers in the next step.

```
{
  "method": "GET",
  "path": "/products",
  "params": {
    "offset": "{{ productsTable.paginationOffset || 0 }}",
    "limit": "100",
    "keyword": "{{ searchInput.value || '' }}",
    "enabled": "true",
    "inStock": "{{ stockFilter.value || '' }}"
  }
}
```

**Expected result:** The getProducts query returns a JSON object with an 'items' array of product objects and a 'total' count. The getOrders query similarly returns order objects in an 'items' array.

### 4. Transform responses and build the product catalog table

Ecwid's API returns product objects with nested structures for price ranges, categories, images, and combinations (variants). Flatten these into a single table-friendly object using a JavaScript transformer. In the getProducts query editor, click 'Advanced' → toggle 'Transform results'. Write a transformer that maps each product in data.items to a flat row. Key fields to extract include id, name, sku, price (from the defaultDisplayedPrice field or price field), quantity (stock level), enabled (visibility status), categories (join category names), and the first image thumbnail URL. After writing the transformer, drag a Table component onto the canvas. Set its Data source to {{ getProducts.data }}. Configure visible columns and set appropriate column types — for example, set enabled to Boolean for a toggle display, price to Currency, and quantity to Number. Enable server-side pagination on the Table and connect it to Ecwid's total field using {{ getProducts.rawData.total }} as the total row count. Add a TextInput component above the table for keyword search — wire it to getProducts so the query re-runs when the search value changes (set getProducts trigger mode to 'Automatic' with a dependency on searchInput.value). Wire column visibility and sorting controls as needed for your team's workflow.

```
// Transformer: flatten Ecwid product list
const items = data.items || [];
return items.map(product => ({
  id: product.id,
  name: product.name,
  sku: product.sku || 'N/A',
  price: product.price || product.defaultDisplayedPrice || 0,
  compare_price: product.compareToPrice || '',
  quantity: product.quantity,
  unlimited_stock: product.unlimited,
  in_stock: product.unlimited ? true : product.quantity > 0,
  enabled: product.enabled,
  category: (product.categories || [])
    .map(c => c.name).join(', ') || 'Uncategorized',
  image_url: product.thumbnailUrl || product.imageUrl || '',
  created: product.created
    ? new Date(product.created * 1000).toLocaleDateString()
    : 'N/A',
  updated: product.updated
    ? new Date(product.updated * 1000).toLocaleDateString()
    : 'N/A'
}));
```

**Expected result:** The products Table displays flat rows with name, SKU, price, stock quantity, and visibility status. Pagination works correctly with the total count from Ecwid's API response.

### 5. Add order management and product update capabilities

For a complete store management panel, add write operations for common tasks: updating order fulfillment status, adding tracking numbers, and updating product stock levels. For order status updates, create a new query: Method PUT, URL path /orders/{{ ordersTable.selectedRow.orderNumber }}, Body type JSON. The body should be a JSON object with the fields to update: { "fulfillmentStatus": "{{ statusSelect.value }}", "trackingNumber": "{{ trackingInput.value }}" }. On the query's Success event handler, trigger getOrders to refresh the table and show a 'Order updated' notification. For product stock updates, create a PUT query with path /products/{{ productsTable.selectedRow.id }} and body { "quantity": {{ quantityInput.value }} }. Wire the Success handler to re-run getProducts and show a notification. Drag a Container component onto the canvas to serve as the order detail panel. Inside it, add Select and TextInput components for status and tracking number, a summary of the order's items, and a 'Save Changes' button. Show this container only when a row is selected in the orders table by setting the container's Hidden property to {{ !ordersTable.selectedRow }}. For complex multi-store inventory sync, automated order routing, and integration with shipping carriers, RapidDev's team can help build a comprehensive Retool Ecwid management solution.

```
{
  "method": "PUT",
  "path": "/orders/{{ ordersTable.selectedRow.orderNumber }}",
  "body": {
    "fulfillmentStatus": "{{ statusSelect.value }}",
    "trackingNumber": "{{ trackingInput.value }}",
    "trackingUrl": "{{ trackingUrlInput.value }}"
  }
}
```

**Expected result:** Selecting an order row shows the detail panel. Updating the status and clicking Save sends the PUT request to Ecwid and refreshes the orders table. Stock level updates on the products table work similarly.

## Best practices

- Store your Ecwid access token as a secret configuration variable in Retool (Settings → Configuration Variables, marked as secret) and reference it in the resource rather than pasting it directly into the token field.
- Include your Ecwid Store ID in the resource base URL (https://app.ecwid.com/api/v3/{store_id}) rather than in every query path — this ensures all queries consistently target the correct store and reduces the chance of configuration errors.
- Use Ecwid's offset and limit parameters with Retool's server-side Table pagination rather than fetching all products at once — large catalogs with thousands of SKUs will hit timeout limits and slow query performance.
- Handle Ecwid's unlimited stock pattern explicitly in transformers — check the 'unlimited' boolean field and display 'Unlimited' in the quantity column rather than showing -1 or 0.
- Add query-level error handling for PUT and DELETE operations using the Failure event handler to show a notification with the error message when an update fails, rather than leaving users with a silently broken form.
- Test write queries (PUT, POST) with a single record in non-production data before exposing bulk update buttons to operations staff — Ecwid API changes are immediate and reversals must be done manually.
- For stores with frequent order volume, add automatic query refresh on getOrders (Advanced tab → Run query on a schedule, every 2-5 minutes) so the fulfillment team always sees the latest incoming orders.

## Use cases

### Build an order management and fulfillment panel

Your fulfillment team needs to view new Ecwid orders, filter by fulfillment status, update order status as items are packed and shipped, and add tracking numbers. A Retool app queries the Ecwid orders endpoint, displays results in a Table with status filter controls, and provides a form to mark orders as shipped and add tracking information via PATCH requests.

Prompt example:

```
Build an order fulfillment panel that lists all Ecwid orders filtered to 'AWAITING_PROCESSING' status with columns for order number, customer name, items ordered, total, and created date. Add a status filter dropdown and a date range picker. Include a row click handler that opens a side panel to update order status and add a tracking number via a PATCH request.
```

### Create a product catalog bulk editor

Your merchandising team needs to bulk-update product prices, update stock counts, or change product visibility across many items at once. A Retool panel fetches the full product catalog with search and category filters, allows inline editing of price and stock fields, and submits bulk updates via PUT requests to the Ecwid products API.

Prompt example:

```
Build a product catalog editor that lists all Ecwid products with columns for name, SKU, price, stock quantity, and visibility status. Add a search input and category filter. Enable inline table editing for the price and stock columns. Add a 'Save Changes' button that loops through edited rows and submits PUT requests to update each changed product.
```

### Build a sales analytics dashboard

Your store manager wants a high-level view of sales performance by day, week, and product category — something Ecwid's native reports do not provide with enough flexibility. A Retool app queries completed Ecwid orders over a date range, transforms the data with a JavaScript aggregation, and displays a Line Chart of daily revenue alongside a Table of top-selling products ranked by units sold.

Prompt example:

```
Build a sales analytics dashboard with a date range picker that queries Ecwid orders for completed sales. Use a JavaScript transformer to aggregate order totals by day and display a Line Chart of daily revenue. Add a second table showing top products by units sold over the selected period. Include a summary row with total revenue and average order value.
```

## Troubleshooting

### Query returns 403 Forbidden or 'Access denied'

Cause: The access token does not have the required scope for the operation. For example, a token with only 'read_catalog' scope will fail when attempting to update a product, and a token with only 'read_orders' will fail when trying to fetch product data.

Solution: Review your Ecwid access token's scopes in the Ecwid Control Panel. If you need broader access, generate a new token with the required scopes (read_catalog, update_catalog, read_orders, update_orders) and update the Bearer token in your Retool resource configuration.

### Product transformer returns empty items array despite visible data in the raw response

Cause: The transformer accesses data.items but the actual raw response structure uses a different wrapping. Ecwid's product endpoint returns { total, count, offset, limit, items }, but if the transformer receives the already-parsed response, the access path may differ.

Solution: Click the 'State' tab in the query result panel to inspect the exact structure the transformer receives. If data.items is undefined, try data.products or check if the response is wrapped differently for your API version. Add a safe fallback: const items = data.items || data.products || (Array.isArray(data) ? data : []).

```
const items = data.items || data.products || (Array.isArray(data) ? data : []);
return items.map(p => ({ id: p.id, name: p.name, price: p.price }));
```

### PUT request to update an order returns 404 Not Found

Cause: Ecwid orders are referenced by 'orderNumber' (human-readable, like #1001) rather than an internal ID in the API path. The correct path parameter is the numeric order number without the # prefix.

Solution: Confirm that ordersTable.selectedRow.orderNumber returns a plain numeric value, not a formatted string with '#'. In your transformer, ensure the orderNumber field is stored as a number or clean string. If the field comes with a '#' prefix from Ecwid's display format, strip it in the transformer using String(order.orderNumber).replace('#', '').

### Images are not displaying in the Table or Image components

Cause: Ecwid product images are served from Ecwid's CDN with URLs that may require HTTPS. The thumbnailUrl or imageUrl field may be empty for products without images.

Solution: In the transformer, add a fallback for missing images: image_url: product.thumbnailUrl || product.imageUrl || 'https://via.placeholder.com/60?text=No+Image'. Ensure the Table column type is set to 'Image' in Retool's column configuration panel, and that the URL in the data is a fully-qualified HTTPS URL.

## Frequently asked questions

### Does Retool have a native Ecwid connector?

No. Ecwid does not have a dedicated native connector in Retool. You connect via a generic REST API Resource using Ecwid's REST API v3. This provides full access to all Ecwid endpoints including products, orders, customers, categories, discount coupons, and store settings — covering all the operations you need for building a custom admin panel.

### What Ecwid plan do I need to use the REST API?

Ecwid's REST API is available on paid plans. The Venture plan and above provide API access. The Free plan does not include API access. Some advanced API features like webhooks require the Business plan or higher. Check Ecwid's pricing page to confirm which plan tier covers the specific API features your Retool integration requires.

### Can I manage multiple Ecwid stores from a single Retool app?

Yes. Create separate REST API Resources in Retool for each Ecwid store, each with its own store ID in the base URL and corresponding access token. In your Retool app, add a Select dropdown that maps to different resource names, and use Retool's resource name variable to switch between stores dynamically in your queries.

### How do I handle Ecwid's pagination for stores with thousands of products?

Ecwid's API returns a maximum of 100 items per request. Use the offset parameter with Retool Table's server-side pagination feature — set the Table's Pagination type to 'Server-side' and pass {{ productsTable.paginationOffset }} as the offset in your query. Set the Table's total row count to {{ getProducts.rawData.total }} (the pre-transformer raw response) so the pagination controls know how many pages to display.

### Can Retool receive webhook events from Ecwid when orders are placed?

Yes. Ecwid supports outbound webhooks that fire when orders are created or updated. Create a Retool Workflow with a Webhook trigger to receive these events — Retool generates a unique webhook URL. Configure Ecwid webhooks (Control Panel → Settings → Webhooks) to point to your Retool Workflow URL. The workflow can then process the event, update a Retool Database record, or trigger a notification to your team.

---

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