# How to Integrate Retool with ShipBob

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

## TL;DR

Connect Retool to ShipBob by adding a REST API Resource with ShipBob's base URL and Personal Access Token. Once configured, query orders, inventory levels, and warehouse data to build a 3PL fulfillment dashboard. The setup takes about 20 minutes and enables real-time visibility into ShipBob inventory, fulfillment SLAs, and shipment status across all warehouses.

## Why Connect Retool to ShipBob?

ShipBob's merchant dashboard provides standard views of orders and inventory, but operations teams managing high-volume e-commerce often need custom visibility that ShipBob's native UI doesn't offer — cross-warehouse inventory comparison, fulfillment SLA tracking, orders filtered by SKU or channel, and bulk action workflows for exception handling. Retool gives you the query builder and component library to construct exactly those tools on top of ShipBob's REST API in a fraction of the time it would take to build a standalone application.

The ShipBob API exposes endpoints for orders (list, get, cancel), inventory (levels by warehouse, by product), products, receiving (inbound shipments), returns, and fulfillment centers. This covers the full operational surface of a 3PL relationship — from the moment a product arrives at a ShipBob warehouse to the moment a customer order ships out. Connecting these data streams to Retool lets you build dashboards like: inventory reorder panels that show SKUs below safety stock levels, fulfillment exception queues for orders stuck in processing, and receiving dashboards that track inbound inventory against expected arrivals.

Because Retool proxies all requests server-side, your ShipBob API token never reaches the browser, and CORS is never an issue. For operations teams that also use a PostgreSQL database for their own product catalog or order management, Retool lets you join ShipBob data with your internal database in a single JavaScript query — comparing your own records with ShipBob's fulfillment state to spot discrepancies.

## Before you start

- A ShipBob merchant account with API access enabled (available on all paid plans)
- A ShipBob Personal Access Token generated from your merchant dashboard under Settings → API Tokens
- A Retool account (Cloud or self-hosted) with permission to add Resources
- Basic familiarity with Retool's query editor and component panel
- Optional: a PostgreSQL or other database Resource already configured in Retool if you want to join ShipBob data with internal records

## Step-by-step guide

### 1. Generate a ShipBob Personal Access Token

Before configuring Retool, you need a ShipBob API token. Log into your ShipBob merchant dashboard at app.shipbob.com. Navigate to Settings in the left sidebar, then select API Tokens from the settings menu. Click the Generate New Token button. Give the token a descriptive name like 'Retool Integration' so you can identify and revoke it later if needed. ShipBob displays the token value once — copy it immediately and store it in a secure location such as a password manager or your team's secrets vault. You will not be able to view the full token again after leaving this page.

ShipBob Personal Access Tokens are scoped to your merchant account and have access to all API endpoints, including read and write operations for orders, inventory, products, and receiving. There is currently no granular scope selection — the token grants full API access. For this reason, treat the token as a high-privilege credential: do not commit it to source control, do not share it in plaintext, and do not embed it in any client-side code. In Retool, you will store it as a configuration variable marked as secret so it is never exposed to the browser.

If you are running Retool self-hosted, you can also store the token as a RETOOL_EXPOSED_ environment variable in your infrastructure configuration, but the configuration variable approach works on both Cloud and self-hosted and is easier to rotate without requiring a container restart.

**Expected result:** You have a ShipBob Personal Access Token copied and stored securely, ready to paste into Retool's resource configuration.

### 2. Add a ShipBob REST API Resource in Retool

Open Retool and navigate to the Resources tab in the left sidebar of the home page (or click Resources in the top navigation bar). Click the Add Resource button in the top-right corner. In the resource type selector, scroll to find REST API or type it in the search bar, then click REST API.

In the resource configuration form, fill in the following fields:
- Name: Enter a descriptive name such as 'ShipBob API' or 'ShipBob Production'. This name appears in the query editor's Resource dropdown.
- Base URL: Enter https://api.shipbob.com/1.0 — this is ShipBob's versioned API base URL. All query paths you write later will be appended to this base.
- Authentication: In the Authentication dropdown, select Bearer Token. In the Bearer Token field, do not paste your actual token directly here. Instead, reference a configuration variable: enter {{ environment.variables.SHIPBOB_API_TOKEN }} in the Bearer Token field.

Before saving, go to Settings → Configuration Variables in your Retool account (accessible from the top-right user menu or sidebar). Click Add Variable, enter SHIPBOB_API_TOKEN as the variable name, paste your ShipBob token as the value, and check the Mark as Secret checkbox. Secret configuration variables are never sent to the browser — they resolve only in server-side resource configurations and Workflows.

Return to the resource configuration and click Save Changes. Retool stores the resource with the token securely referenced via the configuration variable. To verify the connection, you can create a test query pointing to /orders with a GET request and check that you receive a valid JSON response.

**Expected result:** A ShipBob API Resource appears in your Resources list. Test queries using this resource return ShipBob API data. The API token is stored as a secret configuration variable and never visible in query responses.

### 3. Query ShipBob orders and inventory data

Open a Retool app (or create a new one). In the bottom Code panel, click the + New button to create a new query. Select your ShipBob API resource from the Resource dropdown. The query editor shows fields for Method, URL path, Params, Headers, and Body.

For a basic orders query, configure:
- Method: GET
- URL: /orders
- Params: Add query parameters for filtering and pagination. ShipBob supports page (integer, starting at 1), limit (integer, max 250), StartDate (ISO 8601 datetime), EndDate (ISO 8601 datetime), Status (e.g., 'Processing', 'Completed', 'Exception'), and ChannelId.

Set Trigger to Automatically run when inputs change and enable Run this query on page load so orders load immediately when the app opens. In the Advanced tab of the query, add a Transformer to reshape the response:

For inventory queries, create a second query:
- Method: GET
- URL: /inventory
- Params: Add Page and Limit parameters. The inventory endpoint returns product inventory objects with fields for product_id, name, total_fulfillable_quantity, total_onhand_quantity, total_committed_quantity, and per-warehouse breakdown under the fulfillment_center_quantities array.

Bind the orders query result to a Table component by dragging a Table from the Component panel onto the canvas and setting its Data property to {{ ordersQuery.data }}. Configure columns to show the fields most relevant to your operations — ShipBob order objects include id, status, created_date, estimated_fulfillment_date, shipping_method, and a nested recipient object with name and address. Use column formatters to display dates in a readable format and status values as colored badges.

```
// JavaScript transformer for ShipBob orders query
// Add as query transformer in the Advanced tab
const orders = data;
return orders.map(order => ({
  id: order.id,
  reference_id: order.reference_id || 'N/A',
  status: order.status,
  created_date: new Date(order.created_date).toLocaleDateString(),
  customer_name: order.recipient ? order.recipient.name : 'N/A',
  customer_email: order.recipient ? order.recipient.email : 'N/A',
  shipping_method: order.shipping_method || 'Standard',
  est_fulfillment_date: order.estimated_fulfillment_date
    ? new Date(order.estimated_fulfillment_date).toLocaleDateString()
    : 'Pending',
  warehouse: order.fulfillment_center ? order.fulfillment_center.name : 'Unassigned',
  items_count: order.products ? order.products.length : 0
}));
```

**Expected result:** A Table in your Retool app displays ShipBob orders with readable column formatting. An inventory query returns product stock levels per warehouse. Both queries run automatically on page load.

### 4. Build an inventory visibility panel with warehouse breakdown

ShipBob's inventory API returns a fulfillment_center_quantities array on each inventory item — a list of objects showing how much stock is available at each individual warehouse. To display this in Retool's Table component in a useful way, you need to transform the nested data structure into a flat format.

Create a JavaScript transformer (click the Transformer option in the Code panel sidebar, or add it inline on the inventory query in the Advanced tab). The transformer receives the raw API response as data and should return a flat array of rows, one per SKU:

After creating the flattened inventory dataset, bind it to a Table component. Configure the table columns to show: Product Name, SKU, Total Available, Total On Hand, Total Committed, and one column per warehouse (you can generate these dynamically from your transformer output). Add conditional column styling — for example, set the 'Total Available' column to show a red badge when the value is below a configurable threshold.

To make the safety stock threshold configurable, add a Number Input component to the app canvas labeled 'Safety Stock Threshold'. In the Table's column configuration for 'Total Available', add a Row Color rule: when the value in that column is less than {{ safetyStockInput.value }}, apply a red background color (#FEE2E2) and red text (#991B1B).

Below the inventory table, add a Chart component to visualize stock distribution. Set the Chart type to Bar and configure the series to show Total Fulfillable Quantity by warehouse across your top products. This gives operations managers an at-a-glance view of where inventory is concentrated.

```
// JavaScript transformer for ShipBob inventory query
// Flattens warehouse-level quantities into a table-ready structure
const inventory = data;
return inventory.map(item => {
  const warehouseData = {};
  if (item.fulfillment_center_quantities) {
    item.fulfillment_center_quantities.forEach(fc => {
      warehouseData[fc.name + '_available'] = fc.fulfillable_quantity;
      warehouseData[fc.name + '_onhand'] = fc.onhand_quantity;
    });
  }
  return {
    product_id: item.id,
    name: item.name,
    sku: item.sku || 'N/A',
    total_available: item.total_fulfillable_quantity || 0,
    total_onhand: item.total_onhand_quantity || 0,
    total_committed: item.total_committed_quantity || 0,
    is_active: item.is_active ? 'Active' : 'Inactive',
    ...warehouseData
  };
});
```

**Expected result:** The inventory panel shows all ShipBob products with per-warehouse stock levels in a flat Table format. Rows below the safety stock threshold are highlighted in red. A Bar Chart shows inventory distribution across warehouses for the top products.

### 5. Set up a Retool Workflow for low-inventory alerting

For automated monitoring that runs without any user being logged into the Retool app, use Retool Workflows. Navigate to the Workflows section in the Retool home page sidebar (look for the lightning bolt icon). Click New Workflow to open the canvas.

Click Add Trigger and select Schedule. Configure it to run once per day — for example, every day at 7 AM in your business timezone. This ensures your team starts each day with an inventory alert if any SKUs are critically low.

Add a Resource Query block and connect it to your ShipBob API resource. Set Method to GET and path to /inventory. Set limit to 250 to fetch as many products as possible in a single call. For larger catalogs, you may need a Loop block to paginate through multiple pages.

Add a JavaScript Code block after the inventory query. In this block, filter the inventory results to identify SKUs below your alert threshold:

Add a third block — another Resource Query block configured to use your Slack resource (or email resource). In the message field, reference the output of the JavaScript block using the block's name variable (e.g., {{ jsBlock1.data }}) to construct an alert message listing the at-risk SKUs with their current quantities.

Finally, add a Branch (conditional logic) block before the Slack notification block. Set the condition to {{ jsBlock1.data.length > 0 }} — this ensures the Slack alert only fires when there are actually low-stock items, preventing daily empty notifications.

Click Publish Release to activate the workflow. Check the Runs tab to monitor execution history after the first scheduled run.

```
// JavaScript Code block in Retool Workflow
// Filter inventory for SKUs below threshold
const inventory = block1.data; // reference your inventory query block name
const THRESHOLD = 50; // units below which to alert

const lowStockItems = inventory
  .filter(item => item.is_active && item.total_fulfillable_quantity < THRESHOLD)
  .map(item => ({
    name: item.name,
    sku: item.sku,
    available: item.total_fulfillable_quantity,
    onhand: item.total_onhand_quantity
  }))
  .sort((a, b) => a.available - b.available); // lowest stock first

return lowStockItems;
```

**Expected result:** The Workflow appears in Published state. On the scheduled trigger, it fetches ShipBob inventory, identifies low-stock SKUs, and posts a Slack alert only when items are found below the threshold. The Runs tab confirms successful execution.

## Best practices

- Store your ShipBob API token in a Retool configuration variable marked as secret (Settings → Configuration Variables) rather than hardcoding it in the resource or query — this ensures the token never reaches the browser and can be rotated in one place.
- Use ShipBob's StartDate and EndDate parameters on order queries rather than fetching all orders and filtering client-side — server-side filtering is dramatically faster for large order volumes.
- Add pagination controls to inventory and order tables using Retool's built-in Table pagination or custom Previous/Next buttons bound to a page parameter, rather than fetching all records in one call.
- Build separate Retool Resources for different environments if ShipBob provides staging or sandbox accounts — name them 'ShipBob - Staging' and 'ShipBob - Production' and use Retool resource environments to switch between them.
- Use JavaScript transformers to flatten ShipBob's nested JSON responses (especially the fulfillment_center_quantities array) before binding to Table components — nested arrays display poorly in Retool's Table without transformation.
- Set inventory and order queries to Manual trigger mode for dashboards where freshness is less critical, and provide a manual Refresh button — this avoids unnecessary API calls on every component interaction.
- Log all write operations (order cancellations, status updates) to an internal audit table in your database using a chained query in the event handler's On Success step, creating a record of every action taken from Retool.
- Use Retool Workflows for scheduled inventory alerts rather than in-app polling — Workflows run server-side on schedule without requiring a user session and are more reliable for daily operations monitoring.

## Use cases

### Build a live inventory reorder dashboard across ShipBob warehouses

Create a Retool dashboard that queries ShipBob's inventory endpoints to show all SKUs with current stock levels across each fulfillment center. Highlight SKUs below a configurable safety stock threshold in red and provide a bulk export of at-risk SKUs for reorder. Include a Chart component showing 30-day inventory velocity to prioritize which SKUs need restocking most urgently.

Prompt example:

```
Build a Retool inventory dashboard that lists all ShipBob products with their stock levels per warehouse in a Table. Highlight rows in red where total fulfillable quantity is below 50 units. Add a Number Input for adjusting the safety stock threshold. Include a Bar Chart showing the top 10 SKUs by units shipped in the last 30 days. Add an Export button that downloads the filtered low-stock SKUs as a CSV.
```

### Create an order exception queue for stuck ShipBob shipments

Build a Retool operations panel that fetches all ShipBob orders with a status of 'Processing' or 'Exception' and displays them in a Table with order ID, customer name, status reason, and days-in-current-status. Allow ops agents to add internal notes, mark exceptions as resolved, and trigger ShipBob API calls to cancel orders when needed. Log all actions to an internal database for audit trail purposes.

Prompt example:

```
Create a Retool exception queue panel that queries ShipBob for orders in 'Processing' or 'Exception' status filtered to the last 14 days. Show a Table with columns: order ID, customer email, order date, current status, estimated ship date, and warehouse. Add a detail panel on row click showing full order JSON. Include a Cancel Order button that calls ShipBob's cancel endpoint, with a confirmation modal, and writes an audit log entry to the PostgreSQL database.
```

### Monitor inbound receiving against expected inventory arrivals

Build a receiving dashboard that compares ShipBob's receiving orders (inbound shipments) against your internal purchase orders database. Show which inbound shipments are awaiting check-in, which are partially received, and which are fully processed. Include SLA tracking showing how many days each receiving order has been pending, and send Slack alerts for receivings overdue by more than 3 days.

Prompt example:

```
Build a receiving dashboard that fetches all ShipBob receiving orders from the last 60 days and joins them with purchase orders from the PostgreSQL database using PO number. Show a Table with columns: PO number, expected units, received units, percentage received, days since arrival, and ShipBob warehouse. Highlight rows where days since arrival exceeds 3 and status is not 'Completed'. Add a Workflow trigger button that notifies the #logistics Slack channel with overdue receiving details.
```

## Troubleshooting

### ShipBob API returns 401 Unauthorized on all queries

Cause: The Personal Access Token is invalid, expired, or not correctly referenced in the REST API Resource configuration.

Solution: Navigate to Resources tab → click your ShipBob resource → Edit. Verify the Bearer Token field contains {{ environment.variables.SHIPBOB_API_TOKEN }} (using the configuration variable, not the raw token). Then go to Settings → Configuration Variables and confirm the SHIPBOB_API_TOKEN variable exists and contains your valid token. If the token was recently regenerated in ShipBob, update the configuration variable value. Test by creating a simple GET /orders query and clicking Run.

### Inventory query returns an empty array even though ShipBob shows products

Cause: ShipBob's inventory endpoint paginates results and defaults to a small page size. If you have more products than the default page limit, subsequent pages go unqueried.

Solution: Add a limit parameter to your inventory query URL params and set it to 250 (ShipBob's maximum per page). If you have more than 250 SKUs, implement pagination using a Loop block in a Retool Workflow that increments the page parameter until the response returns fewer items than the limit, collecting all pages into a combined result array.

### ShipBob order query returns orders but the fulfillment_center field is null or missing

Cause: Orders that have not yet been processed by ShipBob (status: 'Processing' or 'Pending') may not yet have a warehouse assigned. The fulfillment_center field is only populated after ShipBob routes the order to a specific facility.

Solution: Update your JavaScript transformer to handle null fulfillment_center values with a fallback: use order.fulfillment_center ? order.fulfillment_center.name : 'Not Yet Assigned'. Add a filter in the Table component or query parameters to distinguish between orders awaiting warehouse assignment and those already assigned.

```
// Safe access to nested ShipBob order fields
const warehouse = order.fulfillment_center
  ? order.fulfillment_center.name
  : 'Not Yet Assigned';
const trackingNumber = (order.shipments && order.shipments.length > 0)
  ? order.shipments[0].tracking_number
  : 'Pending';
```

### Retool query times out on large ShipBob inventory or order requests

Cause: Fetching hundreds or thousands of records in a single request, or requesting a very wide date range for orders, causes the query to exceed Retool's default 10-second timeout.

Solution: Reduce the date range on order queries using StartDate and EndDate parameters bound to Retool DateRange components. For inventory, reduce the limit parameter and implement pagination rather than fetching all records at once. In the query's Advanced tab, you can also increase the timeout setting up to 600,000 ms (10 minutes) for Retool Cloud.

## Frequently asked questions

### Does ShipBob have a native Retool connector?

No. ShipBob does not have a dedicated native connector in Retool's Resources catalog. You connect via a generic REST API Resource configured with ShipBob's base URL and your Personal Access Token as a Bearer Token. All ShipBob API endpoints are then queryable from the Retool query editor using GET, POST, and other HTTP methods.

### Can Retool write data back to ShipBob, or is it read-only?

Retool can both read from and write to ShipBob's API. Write operations supported by the ShipBob API include canceling orders (POST /orders/{id}/cancel), creating receiving orders for inbound inventory, and updating order metadata. Configure these as separate queries in Retool with the appropriate HTTP method and request body, triggered by button clicks with confirmation dialogs to prevent accidental execution.

### How do I handle ShipBob's rate limits in Retool?

ShipBob's API enforces rate limits on requests per minute. In Retool, avoid setting queries to Auto mode with high frequency on large datasets. Use Manual trigger queries with explicit refresh buttons for dashboards, and implement pagination rather than fetching all records at once. In Retool Workflows, add a Wait block between loop iterations when paginating through large datasets to avoid hitting rate limits.

### Can I combine ShipBob data with my own database in Retool?

Yes. This is one of Retool's key strengths. Configure both a ShipBob REST API Resource and your database Resource (PostgreSQL, MySQL, etc.) in Retool. In a JavaScript query, use Promise.all to fetch from both resources simultaneously and merge the results client-side — for example, joining ShipBob orders with internal purchase order records by a shared reference ID or order number.

### Does Retool support ShipBob's webhook events?

Retool does not receive incoming webhooks directly, but Retool Workflows can expose a webhook endpoint that you register in ShipBob's settings. When ShipBob fires an event (such as an order status change), it sends a POST request to the Retool Workflow webhook URL, which then processes the event — updating a database, sending a Slack notification, or triggering other actions. This enables event-driven architecture without custom server infrastructure.

---

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