# How to Integrate Retool with Oberlo (now DSers / Shopify)

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

## TL;DR

Oberlo was discontinued by Shopify in June 2022. Connect Retool to your dropshipping operations using Shopify's Admin API (Oberlo's direct replacement) or the DSers API (the official Oberlo alternative for AliExpress dropshipping). Build a dropshipping order tracker that monitors AliExpress fulfillment status, manages Shopify orders, and tracks supplier inventory from a unified Retool dashboard.

## Build a Dropshipping Order Tracker in Retool (Post-Oberlo Migration)

Oberlo was Shopify's flagship dropshipping app, enabling merchants to import products from AliExpress and fulfill orders automatically. Shopify discontinued Oberlo on June 15, 2022, directing all merchants to migrate to DSers — the official AliExpress-authorized dropshipping platform. For Retool users who previously built integrations around Oberlo's API, or who are building new dropshipping operations dashboards, the integration path has shifted entirely to Shopify's Admin API and the DSers platform.

The good news for Retool builders is that Shopify's Admin REST API provides comprehensive access to everything a dropshipping operations dashboard needs: orders (with fulfillment status, line items, and shipping information), products and variants (with inventory levels), fulfillments (including tracking numbers and carrier information from AliExpress via DSers), and customer data. Shopify's API is well-documented, stable, and versioned — making it a reliable foundation for internal dropshipping operations tools.

A typical dropshipping Retool dashboard built on Shopify's API gives operations managers a real-time view of order status across the fulfillment pipeline: which orders are pending AliExpress supplier processing (via DSers), which have been shipped with tracking numbers, and which have delivery exceptions requiring customer communication. Combined with SQL-based analytics against an imported order history database, this dashboard replaces the scattered information spread across Shopify admin, DSers, and AliExpress order tracking pages.

## Before you start

- A Shopify store with an active plan (DSers is installed as a Shopify app and handles AliExpress order routing)
- A Shopify private app or custom app with Admin API access — created in Shopify Admin under Settings → Apps and Sales Channels → Develop Apps
- Shopify Admin API access token with permissions for: read_orders, read_products, read_fulfillments, and read_inventory
- Your Shopify store domain (e.g., yourstore.myshopify.com — used as the API base URL)
- A Retool account with permission to create Resources and Configuration Variables

## Step-by-step guide

### 1. Create a Shopify private app and obtain an Admin API access token

Shopify's Admin REST API uses access token authentication from a custom or private app. To create one, log in to your Shopify admin panel (yourstore.myshopify.com/admin) and navigate to Settings in the bottom-left corner, then Apps and sales channels. Click the Develop apps button (you may need to enable developer tools first by clicking Allow custom app development). Click Create an app and give it a name like 'Retool Dashboard'. Under Configuration, click the Admin API integration tab and click Configure. Select the API scopes (permissions) your Retool dashboard will need: read_orders (to list and view orders), read_fulfillments (to view fulfillment status and tracking), read_products (to view product and variant data), and read_inventory (to view stock levels). If your dashboard will also mark orders or update notes, add write_orders. Click Save. Navigate to the API credentials tab and click Install app — Shopify will generate an Admin API access token. Copy this token immediately — it is shown only once. Store the token in Retool as a Configuration Variable (Settings → Configuration Variables) named SHOPIFY_ACCESS_TOKEN marked as a secret. Also store your store domain as SHOPIFY_STORE_DOMAIN (e.g., yourstore.myshopify.com). Note the current API version from the Shopify changelog (e.g., 2024-01) — always use a stable version in API paths.

**Expected result:** A Shopify private app exists with read_orders, read_fulfillments, read_products, and read_inventory scopes, and the Admin API access token is stored as a Retool Configuration Variable.

### 2. Configure the Shopify Admin REST API Resource in Retool

With your Shopify access token ready, create the REST API Resource in Retool. Navigate to Resources in the left sidebar and click Add Resource. Select REST API. Name the resource 'Shopify Admin API'. Set Base URL to https://{{ retoolContext.configVars.SHOPIFY_STORE_DOMAIN }}/admin/api/2024-01 — replace 2024-01 with your current Shopify API version. Under Authentication, select Header Auth. Add the authentication header with name X-Shopify-Access-Token and value {{ retoolContext.configVars.SHOPIFY_ACCESS_TOKEN }}. This header pattern is Shopify's required method for private app authentication — do not use Bearer token format for Shopify Admin API. Add a default header Content-Type: application/json. Click Save. To test the connection, create a test query: GET /orders.json with URL parameter limit=1, fields=id,name,created_at. A successful response returns a JSON object with an orders array. If you see 401 Unauthorized, verify the X-Shopify-Access-Token header name matches exactly (it is case-sensitive). If you see 403 Forbidden, the app may not have the read_orders scope — return to Shopify admin and verify the app configuration.

**Expected result:** The Shopify Admin API Resource is saved in Retool, and a test query returns a successful order response, confirming that the X-Shopify-Access-Token header is correctly configured.

### 3. Build order queries for the dropshipping dashboard

Create the core data-fetching queries that power the dropshipping operations dashboard. Start with 'getUnfulfilledOrders'. Set Method to GET, Path to /orders.json. Add URL parameters: fulfillment_status → unfulfilled, status → open, limit → 250 (Shopify's maximum per page for REST API), fields → id,name,email,created_at,line_items,total_price,fulfillment_status,financial_status. The response returns an orders array where each order contains line_items (products ordered). Create a JavaScript transformer that flattens the nested line_items, so each row in the Retool Table represents one line item with its parent order details (order number, customer email, order date, days_since_order computed from created_at to now). Sort by days_since_order descending to surface oldest unfulfilled orders first. Create a second query 'getFulfilledOrders' with fulfillment_status=fulfilled for the fulfillment analytics. Add a third query 'searchOrderByNumber' using GET /orders.json with URL parameter name={{ orderSearchInput.value }} for customer service lookup. Shopify order numbers use the # prefix (e.g., #1001) — the name parameter accepts the full string including the hash.

```
// Transformer: flatten Shopify orders with line items
const orders = data?.orders || [];
const flatRows = [];

orders.forEach(order => {
  const daysSince = Math.floor(
    (Date.now() - new Date(order.created_at)) / (1000 * 60 * 60 * 24)
  );
  (order.line_items || []).forEach(item => {
    flatRows.push({
      order_id: order.id,
      order_number: order.name,
      customer_email: order.email || 'N/A',
      order_date: new Date(order.created_at).toLocaleDateString(),
      days_since_order: daysSince,
      product_title: item.title,
      variant_title: item.variant_title || '',
      quantity: item.quantity,
      sku: item.sku || '',
      unit_price: `$${parseFloat(item.price).toFixed(2)}`,
      fulfillment_status: item.fulfillment_status || 'unfulfilled',
      order_total: `$${parseFloat(order.total_price).toFixed(2)}`,
      priority: daysSince > 3 ? 'Overdue' : daysSince > 1 ? 'Normal' : 'New'
    });
  });
});

return flatRows.sort((a, b) => b.days_since_order - a.days_since_order);
```

**Expected result:** The getUnfulfilledOrders query returns a flattened array of line items with order context, priority flags, and days-since-order calculations, ready to display in a Retool Table.

### 4. Build the dropshipping operations dashboard UI

With working queries, assemble the operations dashboard. At the top of the canvas, add three Stat components: 'Unfulfilled Orders' ({{ getUnfulfilledOrders.data.length }} unique order numbers), 'Items to Process' (total line item count), and 'Overdue (3+ days)' ({{ getUnfulfilledOrders.data.filter(r => r.priority === 'Overdue').length }} in red). Below the stats, add a Table component named 'ordersTable' bound to {{ getUnfulfilledOrders.data }}. Configure columns: order_number, customer_email (truncated), product_title, quantity, unit_price, order_date, days_since_order (with conditional color — red for Overdue, orange for Normal, green for New), priority (as a colored Tag). Add a Search Text Input above the table to filter by product_title or order_number using Table's built-in filter. Add a Text Input named 'orderSearchInput' with a Search by Order # button that triggers the searchOrderByNumber query and opens a Modal with the full order details including fulfillment tracking numbers. Add a Fulfillment tab showing the last 50 fulfilled orders (from getFulfilledOrders) with tracking numbers extracted from the fulfillments array in each order. Display a Bar Chart of daily fulfilled order counts over the past 30 days using the fulfilled orders data grouped by order date. For the DSers workflow note: add a text info Banner component explaining that orders marked 'unfulfilled' need to be processed in DSers (dsers.com) to place AliExpress supplier orders — include a link to the DSers dashboard.

**Expected result:** The dropshipping dashboard displays unfulfilled order stats, a prioritized operations table with days-since-order indicators, fulfillment tracking for shipped orders, and a daily fulfillment trend chart.

### 5. Add inventory and product performance analytics

Extend the dashboard with product and inventory analytics to help the dropshipping team make data-driven supplier and product decisions. Create a query 'getProductInventory': GET /products.json with URL parameters: limit → 250, fields → id,title,variants,status. Add a transformer that flattens product variants with their inventory_quantity (from the inventory_item API — requires a second query: GET /inventory_levels.json with inventory_item_ids from the product variants). For simplicity, create a separate Tab panel in the Retool dashboard for Products, showing a Table of all active products with title, variant count, and a sum of inventory across variants. Create a 'getBestSellers' analytics query using a JavaScript transformer over the getFulfilledOrders data: group fulfilled line items by product title, count sold units, and compute total revenue per product over the last 30 days. Display results in a Bar Chart (top 10 products by revenue). Add a 'Slow Movers' view that shows products with zero fulfilled orders in the last 30 days — candidates for removal from the dropshipping catalog. For tracking Shopify inventory sync with AliExpress via DSers, add a last_synced_at note column to a local products tracking table that the ops team updates manually when they verify supplier stock in DSers.

```
// JavaScript transformer: best-selling products by revenue (last 30 days)
const orders = getFulfilledOrders.data || [];
const thirtyDaysAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;

const productMap = {};

orders
  .filter(order => new Date(order.created_at) > thirtyDaysAgo)
  .forEach(order => {
    (order.line_items || []).forEach(item => {
      const key = item.title;
      if (!productMap[key]) {
        productMap[key] = { product: key, units_sold: 0, revenue: 0 };
      }
      productMap[key].units_sold += item.quantity;
      productMap[key].revenue += parseFloat(item.price) * item.quantity;
    });
  });

return Object.values(productMap)
  .sort((a, b) => b.revenue - a.revenue)
  .slice(0, 20)
  .map(p => ({ ...p, revenue: `$${p.revenue.toFixed(2)}` }));
```

**Expected result:** The products tab shows inventory levels and variant counts, the best-sellers chart highlights top-revenue products for the last 30 days, and slow movers are identified for catalog optimization.

## Best practices

- Store your Shopify Admin API access token as a Retool Configuration Variable marked as a secret — never embed it in query bodies or JavaScript code, as the token grants full access to your store data within its configured scopes
- Use a fixed Shopify API version in your Resource base URL (e.g., /admin/api/2024-01) rather than /admin/api/unstable — stable versions are supported for 2 years and provide predictable behavior for production dashboards
- Filter order queries by date range (created_at_min parameter) rather than pulling all orders, since dropshipping stores with high volume can have thousands of orders — a 30-day window is sufficient for most operations dashboards
- Create a local tracking database table alongside Shopify data to store operations team annotations: which orders have been actioned in DSers, custom notes, and escalation flags — Shopify's order notes field is write-accessible but shared with customers
- Monitor days-since-order as a primary KPI on the dashboard — AliExpress dropshipping SLAs typically require orders to be placed with the supplier within 1-3 business days; highlighting orders approaching or exceeding this threshold prevents customer complaints
- Handle Shopify's pagination limit (250 orders per REST API request) explicitly in your queries — for high-volume stores, implement cursor-based pagination using the Link response header rather than assuming all unfulfilled orders fit in one request
- Test the Retool dashboard with a Shopify development store and sample orders before connecting to the production store — development stores are free, support full API access, and prevent accidental data modifications during development

## Use cases

### Build a dropshipping order fulfillment tracker

Create a Retool order operations panel that displays all Shopify orders filtered by fulfillment status, showing which orders are unfulfilled (pending AliExpress order placement in DSers), partially fulfilled, or shipped with tracking information. Allow ops staff to click an order to see its line items, supplier details, and AliExpress tracking number captured by DSers in the fulfillment record.

Prompt example:

```
Build a Retool dropshipping order tracker. Pull orders from Shopify Admin API filtered by fulfillment_status=unfulfilled. Show in a Table: order number, customer name, product names, order date, days since order, and total. Highlight rows where days since order exceeds 3 (AliExpress orders not placed). On row select, show fulfillment details and tracking numbers.
```

### Build a supplier performance and delivery time dashboard

Create a Retool analytics dashboard that tracks delivery performance by product (and by implication, by AliExpress supplier). Query completed Shopify orders with fulfillment data, calculate average delivery time from order placed to delivered, identify products with consistently long shipping times, and surface which SKUs have the highest cancellation or dispute rates. This helps operations managers optimize product selection and supplier relationships.

Prompt example:

```
Build a Retool supplier performance dashboard. Query Shopify fulfilled orders from the past 90 days. Calculate average days from created_at to fulfillment updated_at per product SKU. Show a Table sorted by avg delivery time descending. Include a Chart showing delivery time distribution. Add a filter for product title to drill into specific suppliers.
```

### Build a daily order processing operations panel

Create a Retool morning operations dashboard for the dropshipping team to review the previous day's orders, identify items that need to be placed in DSers (orders not yet submitted to AliExpress), flag high-value orders for priority processing, and mark orders as reviewed once actioned. This replaces the manual Shopify admin and DSers dashboard review process with a single, purpose-built tool.

Prompt example:

```
Build a Retool daily order ops panel. Show yesterday's Shopify orders with unfulfilled status grouped by product. Include a checkbox column for 'Actioned in DSers' that saves to a local tracking table. Show total order value, order count, and a priority flag for orders over $100. Add a notes field for each order.
```

## Troubleshooting

### Shopify API returns 401 Unauthorized — 'Invalid API key or access token'

Cause: The X-Shopify-Access-Token header is missing, contains an incorrect token value, or the private app has been uninstalled from the Shopify store since the token was generated.

Solution: Verify the token exists and is active: go to Shopify Admin → Settings → Apps and sales channels → Develop apps, select your app, and check the API credentials tab. If the app has been reinstalled or the token was regenerated, copy the new token and update the SHOPIFY_ACCESS_TOKEN Configuration Variable in Retool. Confirm the header name in the Retool Resource is exactly X-Shopify-Access-Token (not Authorization: Bearer, which is for OAuth-based Shopify apps).

### Order query returns empty orders array despite orders existing in Shopify admin

Cause: The URL parameter filters (fulfillment_status, status) may be excluding the orders you expect to see. Shopify's default status filter is 'open', which excludes archived and cancelled orders.

Solution: Try the query without the fulfillment_status parameter first to see all orders. Then add filters incrementally: status=any returns all orders including archived. fulfillment_status=unfulfilled returns only fully unfulfilled orders — orders with partial fulfillment have fulfillment_status=partial, not unfulfilled. Adjust the filter to include both: pass status=open with no fulfillment_status filter and apply client-side filtering in the transformer.

### Shopify API returns 429 Too Many Requests — rate limit exceeded

Cause: Multiple Retool queries are running simultaneously against the Shopify Admin API, depleting the leaky bucket rate limit (40 requests/second, 80 bucket capacity). Auto-refresh queries firing every few seconds compound this issue.

Solution: Set Retool query auto-refresh intervals to 60 seconds minimum rather than shorter intervals. Use event-handler chaining to run queries sequentially (on app load → trigger query1, on query1 success → trigger query2) rather than all simultaneously. Check the X-Shopify-Shop-Api-Call-Limit response header in test runs to understand baseline usage. For dashboards that must refresh frequently, implement Retool query caching to serve repeated identical requests from cache.

### Fulfillment tracking numbers are missing from Shopify order records

Cause: DSers submits AliExpress orders and populates tracking information in Shopify's fulfillment records only after the AliExpress seller ships the package — this can be 3-7 days after DSers processes the order. Orders fulfilled by DSers but not yet shipped by the AliExpress supplier will have a Shopify fulfillment record but an empty tracking_number field.

Solution: Add a conditional display in the order detail panel: if tracking_number is empty in the fulfillment record, show 'Awaiting AliExpress Shipment' rather than an empty tracking field. For orders that are unfulfilled in Shopify (DSers has not yet placed the AliExpress order), show 'Pending DSers Processing'. This distinction helps ops staff understand where each order is in the two-step AliExpress dropshipping pipeline.

## Frequently asked questions

### What happened to Oberlo and how do I migrate to DSers?

Shopify discontinued Oberlo on June 15, 2022, and partnered with DSers as the official replacement for AliExpress dropshipping. If you were using Oberlo, your products and orders should have been migrated automatically to DSers when the transition occurred. For new dropshipping stores, install DSers from the Shopify App Store — it connects your Shopify store to AliExpress supplier products and handles order routing automatically. Your Retool integration connects to Shopify's Admin API (the data source), not to DSers directly.

### Does DSers have a public API that Retool can connect to directly?

DSers does not currently offer a public REST API for third-party integrations. DSers operates as a Shopify app, meaning its data (placed AliExpress orders, tracking numbers, supplier information) flows through Shopify's fulfillment and order APIs. To access DSers fulfillment data in Retool, query Shopify's /orders/{id}/fulfillments endpoint — DSers writes tracking numbers and fulfillment records directly into Shopify's order data.

### How do I view AliExpress order status and tracking in Retool?

AliExpress tracking information appears in Shopify's fulfillment records after DSers processes the order and the AliExpress seller ships the package. Query GET /orders/{order_id}/fulfillments.json to retrieve tracking_number and tracking_company for each fulfilled order. The tracking URL for AliExpress logistics is typically: https://track.aliexpress.com/logisticsdetail.htm?tradeId={tracking_number}. DSers populates this data automatically when AliExpress sellers upload shipping information, usually 3-7 days after the supplier order is placed.

### Can I use Retool to automate placing AliExpress dropshipping orders?

Not directly through a public API. DSers handles AliExpress order placement either manually (you select orders in DSers and click Order) or automatically (DSers Premium+ plans with auto-order features). Since DSers does not expose a public API, automated order placement from Retool would require using Retool Workflows with web automation tools or relying on DSers's built-in automation features. The most practical Retool approach is a dashboard that identifies orders needing DSers processing, with a link to the DSers order management page for the fulfillment step.

### What Shopify API permissions do I need for a complete dropshipping Retool dashboard?

For a read-only operations dashboard: read_orders, read_fulfillments, read_products, and read_inventory. If you want to add order notes, tags, or update order attributes from Retool: add write_orders. For managing product inventory levels: add write_inventory. For processing refunds or cancellations: add write_orders. Start with read-only permissions for your initial build — you can always add write permissions to the Shopify private app later and reinstall it to get an updated token with the expanded scopes.

---

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