# How to Integrate Retool with UPS API

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

## TL;DR

Connect Retool to the UPS API using a REST API Resource with OAuth 2.0 client credentials authentication. Use the UPS Tracking, Rating, and Shipping APIs to build shipment management panels that track packages, calculate shipping rates, and manage order fulfillment — all without navigating the UPS web portal.

## Build a UPS Shipment Management Panel in Retool

E-commerce operations teams spend significant time checking UPS shipment statuses across multiple orders, manually looking up tracking numbers, and calculating shipping costs for quotes. Retool solves this by pulling UPS data directly into an operations dashboard alongside order data from your database or e-commerce platform.

UPS transitioned its API suite to OAuth 2.0 in 2023, deprecating the older username/password authentication method. The modern UPS API uses standard client credentials flow — your application credentials are exchanged for an access token, and that token authenticates subsequent API calls. Tokens expire after approximately one hour, and Retool's Custom Auth system handles refresh automatically.

The most-used UPS API endpoints for Retool integrations are: Tracking v1 for package status and delivery updates, Rating v1 for shipping cost calculations before printing labels, Shipping v2403 for creating shipments and generating labels, and Address Validation for verifying customer addresses before shipping.

## Before you start

- A UPS account registered at developer.ups.com with a UPS application created
- UPS OAuth 2.0 Client ID and Client Secret from the Developer Portal
- A UPS account number (required for shipping label creation and some rate queries)
- A Retool account with permission to create Resources and configure Custom Auth

## Step-by-step guide

### 1. Register a UPS developer application and get OAuth credentials

Navigate to developer.ups.com and sign in with your UPS account credentials. Click 'Add Apps' or navigate to 'My Apps' and create a new application. Give the app a name like 'Retool Integration'. Select the API products you need: Tracking, Rating, and Shipping are the most common for operations dashboards. The application creation generates a Client ID and Client Secret. Copy both values — the Client Secret will only be shown once or can be regenerated if lost, but treat it as a permanent secret. In your Retool configuration variables (Settings → Configuration Variables), create three entries: UPS_CLIENT_ID with your client ID, UPS_CLIENT_SECRET with the client secret (mark as secret), and UPS_ACCOUNT_NUMBER with your UPS account number (needed for rating and shipping queries with your account's negotiated rates). Note that UPS's developer environment and production environment use the same credentials but different base URLs.

**Expected result:** You have UPS Client ID, Client Secret, and Account Number stored in Retool configuration variables.

### 2. Configure Retool REST API Resource with UPS OAuth

Create a REST API Resource in Retool for the UPS API. Set the Base URL to 'https://onlinetools.ups.com' (production) or 'https://wwwcie.ups.com' (testing). Under Authentication, select 'Custom Auth'. Configure the token endpoint call: POST to 'https://onlinetools.ups.com/security/v1/oauth/token' with Content-Type 'application/x-www-form-urlencoded' and body containing grant_type=client_credentials, client_id={{ retoolContext.configVars.UPS_CLIENT_ID }}, and client_secret={{ retoolContext.configVars.UPS_CLIENT_SECRET }}. Store the returned access_token in a variable. Set the Authorization header for all resource requests to 'Bearer {{ ups_access_token }}'. Also add a default 'Content-Type' header with value 'application/json' and a 'transId' header with a unique transaction ID (can use a timestamp: {{ Date.now().toString() }}) and 'transactionSrc' header with a descriptive value like 'retool-ops-dashboard'. The transaction headers are optional but recommended for UPS's logging.

```
// UPS OAuth token request configuration:
// POST https://onlinetools.ups.com/security/v1/oauth/token
// Content-Type: application/x-www-form-urlencoded
// Body:
// grant_type=client_credentials
// client_id={{ retoolContext.configVars.UPS_CLIENT_ID }}
// client_secret={{ retoolContext.configVars.UPS_CLIENT_SECRET }}

// Store: access_token from response
// Token expires in: response.expires_in seconds (typically 14400 = 4 hours)

// Resource headers:
// Authorization: Bearer {{ ups_access_token }}
// Content-Type: application/json
// transId: {{ Date.now().toString() }}
// transactionSrc: retool-ops-dashboard
```

**Expected result:** The UPS REST API Resource is saved with Custom Auth configured. A test query to /api/addressvalidation/v1/1 returns a response (even if with an error about missing request body, confirming auth works).

### 3. Query the UPS Tracking API

Create a query for tracking packages. Use GET method with path '/api/track/v1/details/{{ trackingInput.value }}'. The path parameter is the UPS tracking number. Add a query parameter 'locale' set to 'en_US' and 'returnSignature' set to 'false'. The response contains a 'trackResponse' object with a 'shipment' array. Each shipment has 'currentStatus' (the latest status), 'deliveryDate', and 'activity' array with full scan history. Add a transformer to extract the current status, last activity, and estimated delivery. Bind a TextInput component for the tracking number input and a Button to trigger the query. Display the tracking result in a well-formatted Container component showing the current status, delivery estimate, and activity timeline.

```
// GET /api/track/v1/details/{{ trackingInput.value }}
// Query parameters: locale=en_US, returnSignature=false

// Transformer: extract tracking summary
const shipment = data?.trackResponse?.shipment?.[0];
if (!shipment) return { error: 'No tracking data found' };

const activities = shipment.activity || [];
const latestActivity = activities[0] || {};

return {
  tracking_number: shipment.trackingNumber,
  status: shipment.currentStatus?.description || 'Unknown',
  status_code: shipment.currentStatus?.code || '',
  estimated_delivery: shipment.deliveryDate?.[0]?.date || 'Not available',
  last_location: latestActivity.location?.address
    ? `${latestActivity.location.address.city}, ${latestActivity.location.address.stateProvince}`
    : 'Unknown',
  last_activity: latestActivity.description || '',
  last_updated: latestActivity.date
    ? `${latestActivity.date} ${latestActivity.time || ''}`
    : 'Unknown',
  activity_history: activities.slice(0, 10).map(a => ({
    date: `${a.date} ${a.time || ''}`.trim(),
    description: a.description || '',
    location: a.location?.address
      ? `${a.location.address.city || ''}, ${a.location.address.stateProvince || ''}`.trim()
      : ''
  }))
};
```

**Expected result:** Entering a valid UPS tracking number and clicking the tracking button returns current shipment status, estimated delivery date, and activity history.

### 4. Build a shipping rate calculator

Create a POST query using the UPS Rating API to calculate shipping rates. Use path '/api/rating/v2403/Rate' and set the method to POST. The request body is a JSON object with a RateRequest wrapper containing shipper information (your UPS account number), ship-from and ship-to addresses, and package details (weight, dimensions, packaging type). The response returns rates for the requested service type, or use service code '03' (UPS Ground) and '01' (Next Day Air) for comparison. Add form components to your Retool app for origin/destination zip codes, weight, and dimensions. Wire the form submit button to run the rating query and display results in a Table component showing service type, rate, and transit days.

```
// POST /api/rating/v2403/Rate
// Request body:
{
  "RateRequest": {
    "Request": {
      "RequestOption": "Shop"
    },
    "Shipment": {
      "Shipper": {
        "ShipperNumber": "{{ retoolContext.configVars.UPS_ACCOUNT_NUMBER }}",
        "Address": {
          "PostalCode": "{{ originZip.value }}",
          "CountryCode": "US"
        }
      },
      "ShipTo": {
        "Address": {
          "PostalCode": "{{ destZip.value }}",
          "CountryCode": "US",
          "ResidentialAddressIndicator": ""
        }
      },
      "ShipFrom": {
        "Address": {
          "PostalCode": "{{ originZip.value }}",
          "CountryCode": "US"
        }
      },
      "Service": { "Code": "03" },
      "Package": {
        "PackagingType": { "Code": "02" },
        "PackageWeight": {
          "UnitOfMeasurement": { "Code": "LBS" },
          "Weight": "{{ weight.value }}"
        }
      }
    }
  }
}
```

**Expected result:** Entering origin/destination zip codes and package weight displays a table of UPS shipping rates across all available service levels with transit time estimates.

### 5. Build a multi-shipment status monitoring table

For order fulfillment dashboards, you need to track multiple shipments simultaneously rather than one at a time. Create a query that reads tracking numbers from your orders database (using a separate PostgreSQL or REST API resource), then uses a Retool Workflow to batch query UPS tracking status for each shipment and store results back into a tracking_status table. Alternatively, for smaller volumes (under 20 active shipments), use Retool's query chaining: a JavaScript query loops through tracking numbers, calling the UPS tracking query for each, and aggregates results into an array. Display the results in a Table with conditional row highlighting — green for delivered, yellow for in transit, red for exception. For complex fulfillment automation connecting UPS with your order management system and notification workflows, RapidDev's team can architect the complete solution.

```
// JavaScript query: batch track multiple shipments
// Reads tracking numbers from database query 'getOrders.data'
const orders = getOrders.data || [];
const trackingNumbers = orders
  .filter(o => o.tracking_number && o.tracking_number.trim())
  .map(o => o.tracking_number.trim());

// Return array for display while workflow fetches live data
// (Use Retool Workflows for actual batch UPS API calls)
return trackingNumbers.map(tn => ({
  tracking_number: tn,
  status: 'Pending refresh',
  last_updated: new Date().toLocaleDateString()
}));
```

**Expected result:** The shipment monitoring table displays all active orders with their tracking numbers and last-known UPS status, with color coding for at-risk or delayed shipments.

## Best practices

- Store UPS Client ID and Client Secret in Retool configuration variables as secrets — never include them in request bodies or URLs
- Use UPS's test environment (wwwcie.ups.com) with test credentials during development to avoid creating real shipments or incurring charges
- Cache tracking query results for 15-30 minutes — package tracking data does not change more frequently than that in normal circumstances, and caching reduces API calls
- Include transaction IDs in UPS API requests (transId header) to help UPS support diagnose issues when you contact them about specific API calls
- Build graceful error handling for tracking queries — UPS tracking data may be temporarily unavailable for just-created shipments, and transformers should handle missing data without JavaScript errors
- For high-volume shipment monitoring, set up UPS Quantum View webhooks to push status updates to a Retool Workflow endpoint rather than polling individual tracking numbers

## Use cases

### Build a multi-order shipment tracking dashboard

Display all recent orders from your database alongside real-time UPS tracking status. Query tracking numbers from your database and batch them against the UPS Tracking API to show current package status, estimated delivery date, and last scan location. Highlight delayed or exception shipments requiring customer communication.

Prompt example:

```
Build a Retool fulfillment dashboard that reads tracking numbers from a PostgreSQL orders table, queries UPS Tracking API for each, and shows a unified view of order status, shipment status, estimated delivery, and current package location.
```

### Create a shipping rate calculator for operations teams

Build a Retool tool where operations staff can enter a package weight, dimensions, origin zip, and destination zip to get UPS shipping rates across all service levels (Ground, 2-Day Air, Next Day Air). Display rates in a comparison table to help select the most cost-effective service for each shipment.

Prompt example:

```
Create a Retool shipping rate calculator with form fields for origin zip, destination zip, weight, and dimensions. On submit, call UPS Rating API and show a table comparing rates for all UPS service types with transit days and price.
```

### Build an exception and delay monitoring panel

Create a Retool app that runs on a schedule to check all in-transit shipments for delivery exceptions, delays, or weather holds. Surface these in a prioritized list for customer service teams to proactively communicate with affected customers before they contact support.

Prompt example:

```
Build a Retool exceptions panel connected to UPS Tracking that shows all shipments with status 'Exception' or delivery date past today's date, sorted by days delayed, with customer email addresses for outreach.
```

## Troubleshooting

### OAuth token request returns 'invalid_client' error

Cause: The Client ID or Client Secret does not match the application registered in UPS Developer Portal, or the application is in a different environment (testing vs production). Also possible: the application was not activated or approved after creation.

Solution: Log into developer.ups.com and verify the application status is 'Active'. Copy the Client ID and Secret directly from the portal rather than from notes. Ensure you are using the matching base URLs: wwwcie.ups.com for test credentials, onlinetools.ups.com for production credentials.

### Tracking API returns 'No tracking information found' for a valid tracking number

Cause: The tracking number may be too new (UPS takes 1-2 hours to enter tracking data after label creation), may have expired from UPS records (retained for ~120 days), or the test environment does not have data for that tracking number.

Solution: For testing, use the UPS-provided sample tracking numbers in the API documentation which have pre-populated test data. For production, verify the tracking number was created more than 2 hours ago. Check that you are querying the correct environment (production vs testing).

### Rating API returns empty rates or 'Service not available for origin/destination'

Cause: The service type requested may not be available for the origin/destination pair, or the account number is missing or invalid. UPS Ground is not available for all international destinations.

Solution: Use RequestOption: 'Shop' to get all available services instead of specifying a single service code. Verify your UPS account number is correctly configured — account number is required for negotiated rates. For international shipments, include CountryCode fields in both origin and destination addresses.

## Frequently asked questions

### Do I need a UPS account to use the UPS API?

You need a UPS.com user account to register as a developer and obtain API credentials. A UPS shipper account number is additionally required for rating with negotiated rates and for creating shipping labels. Basic tracking functionality only requires the developer credentials, not a shipper account number.

### Can I create UPS shipping labels from Retool?

Yes. Use the UPS Shipping API (POST /api/shipments/v2403/ship) to create shipments and generate labels. The response includes a base64-encoded label image (GIF or PDF) that you can display in a Retool Image component or trigger as a download. Shipping label creation requires your UPS account number and a valid ship-from address registered with UPS.

### How long does UPS OAuth access token last?

UPS OAuth access tokens expire after 4 hours (14,400 seconds as indicated by the expires_in field). Retool's Custom Auth refresh handles this automatically when configured to refresh on 401 responses. Unlike some providers, UPS does not provide a refresh token — you must re-authenticate with client credentials each time the token expires.

### Can I track USPS or FedEx packages using the UPS API?

No. The UPS Tracking API only tracks packages shipped via UPS services. For multi-carrier tracking in a single Retool app, you need separate resources for each carrier's API (UPS, FedEx, USPS) or use a multi-carrier aggregator like ShipStation or AfterShip which tracks packages across all carriers through a single API.

---

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